在oracle数据库中,有一个变量绑定的用法,很多人都比较熟悉,可以调高数据库效率,应对高并发等,好吧,这其中并不包括我,当同事问我MySQL中有没有类似的写法时,我是很茫然的,于是就上网查,找到了如下一种写法:
DELIMITER $$
set @stmt = 'select userid,username from myuser where userid between ? and ?';
prepare s1 from @stmt;
set @s1 = 2;
set @s2 = 100;
execute s1 using @s1,@s2;
deallocate prepare s1;
$$
DELIMITER ;
用这种形式写的查询,可以随意替换参数,给出代码的人称之为预处理,我想这个应该就是MySQL中的变量绑定吧……但是,在查资料的过程中我却听
到了两种声音,一种是,MySQL中有类似Oracle变量绑定的写法,但没有其实际作用,也就是只能方便编写,不能提高效率
另一种说法是MySQL中的变量绑定是能确实提高效率的,这个是希望有的,那到底有木有,还是自己去试验下吧。
试验是在本机进行的,数据量比较小,具体数字并不具有实际意义,但是,能用来说明一些问题,数据库版本是mysql-5.1.57-win32免安装版。
本着对数据库不是很熟悉的态度^_^,试验过程中走了不少弯路,此文以结论为主,就不列出实验的设计过程,文笔不好,文章写得有点枯燥,写出来是希望有人来拍砖,因为我得出的结论是:预处理在有没有cache的情况下的执行效率都不及直接执行……
我对自己的实验结果不愿接受。。如果说预处理只为了规范下Query,使cache命中率提高的话个人觉得大材小用了,希望有比较了解的人能指出事实究竟是什么样子的
——
NewSilen
实验准备
第一个文件NormalQuery.sql
Set profiling=1;
Select * From MyTable where DictID = 100601000004;
Select DictID from MyTable limit 1,100;
Select DictID from MyTable limit 2,100;
/*从limit 1,100 到limit 100,100 此处省略重复代码*/
......
Select DictID from MyTable limit 100,100;
SELECT query_id,seq,STATE,10000*DURATION FROM information_schema.profiling INTO OUTFILE 'd:/NormalResults.csv' FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
第二个sql文件 StmtQuery.sql
Set profiling=1;
Select * From MyTable where DictID = 100601000004;
set @stmt = 'Select DictID from MyTable limit ?,?';
prepare s1 from @stmt;
set @s = 100;
set @s1 = 101;
set @s2 = 102;
......
set @s100 =200;
execute s1 using @s1,@s;
execute s1 using @s2,@s;
......
execute s1 using @s100,@s;
SELECT query_id,seq,STATE,10000*DURATION FROM information_schema.profiling INTO OUTFILE 'd:/StmtResults.csv' FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
做几点小说明:
1. Set profiling=1;
执行此语句之后,可以从information_schema.profiling这张表中读出语句执行的详细信息,其实包含不少内容,包括我需要的时间
信息,这是张临时表,每新开一个会话都要重新设置profiling属性才能从这张表中读取数据Often hair is what causes
2. Select * From MyTable where DictID = 100601000004;
这行代码貌似和我们的实验没什么关系,本来我也是这么认为的,之所以加这句,是我在之前的摸索中发现,执行过程中有个步骤是open table,如果是第一次打开某张表,那时间是相当长的,所以在执行后面的语句前,我先执行了这行代码打开试验用的表
3.
MySQL默认在information_schema.profiling表中保存的查询历史是15条,可以修改
profiling_history_size属性来进行调整,我希望他大一些让我能一次取出足够的数据,不过最大值只有100,尽管我调整为150,最
后能够查到的也只有100条,不过也够了
4. SQL代码我没有全列出来,因为查询语句差不多,上面代码中用省略号表示了,最后的结果是两个csv文件,个人习惯,你也可以把结果存到数据库进行分析
实验步骤
重启数据库,执行文件NormalQuery.sql,执行文件StmtQuery.sql,得到两个结果文件
再重启数据库,执行StmtQuery.sql,执行文件NormalQuery.sql,得到另外两个结果文件
实验结果
详细结果在最后提供了附件下载,有兴趣的朋友可以看下
结果分析
每一个SQL文件中执行了一百个查询语句,没有重复的查询语句,不存在查询cache,统计执行SQL的平均时间得出如下结果JS获取最底层iframe页面中鼠标点击的坐标
从结果中可以看出,无论是先执行还是后执行,NormalQuery中的语句都比使用预处理语句的要快一些=.=!
那再来看看每一句查询具体的情况,Normal和Stmt的query各执行了两百次,每一步的详细信息如下:
从这里面可以看出,第一个,normalquery比stmtquery少一个步骤,第二个,虽然stmt在不少步骤上是优于normal的,但在executing一步上输掉太多,最后结果上也是落败
最后,再给出一个查询缓存的实验结果,具体步骤就不列了
在查询缓存的时候,Normal完胜……
写在最后
大概情况就是这样,我回忆了一下,网上说预处理可以提高效率的,基本都是用编程的方式去执行查询,不知道这个有没有关系,基础有限,希望园子里的大牛能看到,帮忙解惑
分享到:
相关推荐
MySQL中的预处理语句(Stmt预处理)是一种优化技术,主要目的是提高数据库处理效率,特别是在高并发场景下。预处理语句允许我们提前编译SQL语句,然后多次执行该语句的不同实例,只需替换参数即可。这与Oracle数据库...
MySQL中的`stmt`是预处理语句(PreparedStatement)的接口,它是提高数据库操作效率和安全性的重要工具。预处理语句允许我们提前编译SQL语句,然后多次执行,每次只需改变参数,而无需重新解析和编译整个SQL,这对于...
MySQL C API 预处理语句是MySQL数据库与C语言交互的一种方式,它允许开发者创建、准备、执行和重用SQL语句,提高了代码的安全性和效率。预处理语句能够防止SQL注入攻击,因为它们在执行之前会被解析和编译,参数化值...
MySQL官方将prepare、execute、deallocate统称为PREPARE STATEMENT,我习惯称其为【预处理语句】,其用法十分简单,下面话不多说,来一起看看详细的介绍吧。 示例代码 PREPARE stmt_name FROM preparable_stmt ...
在PHP和MySQL数据库交互时,预处理语句是一种强大的安全机制,它有助于防止SQL注入攻击,提高代码效率和可读性。预处理语句的工作原理是先定义SQL语句的结构,然后在执行时绑定参数,这样可以确保数据与SQL语法分离...
预处理语句不仅可以用于 `INSERT` 语句,同样适用于 `SELECT`、`UPDATE` 和 `DELETE` 语句等,提高了代码的安全性和效率。 #### 二、PHP MySQL 读取数据 在 PHP 中使用 MySQL 读取数据,通常使用 `SELECT` 语句来...
使用`mysql_stmt_init()`, `mysql_stmt_prepare()`, `mysql_stmt_bind_param()`, `mysql_stmt_execute()`等函数来实现。 八、事务处理 如果你需要确保一系列数据库操作的原子性,可以使用MySQL的事务功能。`START ...
MySQL的PREPARE预处理语句是一种提高数据库操作性能和安全性的重要工具,尤其适用于需要重复执行相同结构但参数不同的SQL语句的情况。预处理语句的工作原理是先定义一个SQL模板,然后在执行时动态插入参数,从而减少...
5. **预处理语句**:预处理语句通过`mysql_stmt_init()`、`mysql_stmt_prepare()`、`mysql_stmt_bind_param()`、`mysql_stmt_execute()`等函数实现,提高了执行效率,增强了安全性。 6. **事务处理**:`mysql_begin...
9. 预处理语句( Prepared Statements):在`mysql_stmt.h`中定义,预处理语句提高了SQL执行的效率和安全性,允许多次执行同一查询模板,只需改变参数值。 10. 连接池管理:在多线程环境中,连接池可以提高性能并...
7. **连接池管理**:在多线程或高并发环境中,可以使用连接池来管理MySQL连接,提高效率并减少资源消耗。 总的来说,`typelib.h`和`mysql.h`头文件是MySQL C/C++编程的基础,它们提供了丰富的API,让开发者能够灵活...
MySQL C API是MySQL数据库系统提供的一种...这个详细的注释版文档将有助于开发者更深入地理解和应用这些API,提高开发效率和代码质量。在阅读文档时,应结合实际项目需求,对相关函数进行学习和实践,以掌握其用法。
7. **预处理语句**:预处理语句通过`mysql_stmt_prepare()`、`mysql_stmt_execute()`等函数提高安全性,防止SQL注入。它们允许参数化查询,将用户输入与SQL语句结构分离。 8. **游标操作**:虽然MySQL API在C语言中...
- `mysql_stmt_prepare()`:准备一个预处理SQL语句。 - `mysql_stmt_bind_param()`:绑定参数到预处理语句。 - `mysql_stmt_execute()`:执行预处理语句。 - `mysql_stmt_bind_result()`:绑定结果到变量。 - `...
此外,MySQL-CAPI还支持预处理语句,通过`mysql_stmt_init()`, `mysql_stmt_prepare()`, `mysql_stmt_bind_param()`, `mysql_stmt_execute()`等函数,提高执行效率并增强安全性。 总的来说,MySQL-CAPI提供了一个...
调用`mysql_stmt_execute()`来执行预处理的存储过程。 6. 获取结果集(如果有的话)。使用`mysql_stmt_store_result()`存储结果集,然后使用`mysql_stmt_fetch()`遍历结果。 7. 关闭结果集,释放资源。调用`mysql_...
- 对于复杂的查询,可以使用 `mysql_stmt_prepare` 和 `mysql_stmt_execute` 函数来预处理并执行 SQL 语句。 - 例如: ```c MYSQL_STMT *stmt = mysql_stmt_init(conn); if (mysql_stmt_prepare(stmt, "INSERT ...
6. **预处理语句**:为了提高性能和安全性,类库可能实现预处理语句,允许开发者在执行前准备SQL语句,使用`mysql_stmt_prepare()`, `mysql_stmt_bind_param()`和`mysql_stmt_execute()`等函数。 7. **资源释放**:...