6 STMT的测试
MySQL的API为什么在网络环境下表现较差?一方面由于MySQL的API全部直接使用SQL语句执行,SQL的分析成本是比较大的,同时每次都要传递SQL也占用带宽,一方面由于MySQL的结果是采用字符串的方式传递的,也是一个比较耗费资源的事情。为了解决这些不足,MySQL推出了一组新的API STMT。(我到现在没有搞明白是什么的缩写?)
STMT是MySQL 4.1版本的一个重要的噱头,其提供一种和以往的API不同的形式访问数据库。其类似Oracle等提供的绑定变量的API方式。
这样的方式基本方法是使用一个绑定参数的SQL,这个SQL在使用前先要进行分析准备(mysql_stmt_prepare),在执行前还必须,为输入参数绑定变量(mysql_stmt_bind_param)比如查询参数,插入语句参数,为输出参数绑定结果(mysql_stmt_bind_result),比如查询语句。下次在进行插入和更新操作时就可以直接修改相关的参数,由于SQL语句已经经过分析,再次处理的速度可以得到大大的提高。
STMT的API基本是由自己独立的一套,如mysql_stmt_execute,mysql_stmt_errno
STMT的重要优势是避免了语法分析SQL的成本,同时由于STMT语句在次执行的时候无需传输大量的SQL语句数据,可以大大减少网络流量,在网络环境下也更有优势。
为了进行横向的比较,我将测试分成两种方法,一种是使用每次都使用Prepare语句的测试,一种是只在第一次使用Prepare语句,后面的操作只更新邦定变量。查询的操作都完成转储结果集。
表18 STMT的性能测试
| MySQL4.1使用传统API的 | MySQL4.1使用STMT API,每次都使用Prepare | MySQL4.1使用STMT API,只有第一次都使用Prepare | |||
耗时(s) | 处理速度(条/s) | 耗时(s) | 处理速度(条/s) | 耗时(s) | 处理速度(条/s) | |
插入1000000条记录 | 176 | 5681.82 | 334 | 2994.01 | 123 | 8130.08 |
查询1000000条记录 | 306 | 3267.97 | 406 | 2463.05 | 170 | 5882.35 |
改写1000000条记录 | 174 | 5747.13 | 279 | 3584.23 | 117 | 8547.01 |
删除1000000条记录 | 179 | 5586.59 | 257 | 3891.05 | 130 | 7692.31 |
插入5000000条记录 | 898 | 5567.93 | 1689 | 2960.33 | 653 | 7656.97 |
查询5000000条记录 | 1595 | 3134.80 | 2020 | 2475.25 | 863 | 5793.74 |
改写5000000条记录 | 859 | 5820.72 | 1430 | 3496.50 | 677 | 7385.52 |
删除5000000条记录 | 976 | 5122.95 | 1380 | 3623.19 | 798 | 6265.66 |
插入10000000条记录 | 1815 | 5509.64 | 3423 | 2921.41 | 1360 | 7352.94 |
查询10000000条记录 | 3257 | 3070.31 | 4065 | 2460.02 | 1742 | 5740.53 |
改写10000000条记录 | 1904 | 5252.10 | 2969 | 3368.14 | 1482 | 6747.64 |
删除10000000条记录 | 1982 | 5045.41 | 2794 | 3579.10 | 1693 | 5906.67 |
相关数据的比较图表如下。
图12 STMT API性能测试
从上面看出,如果每个语句都使用Prepare,居然还慢了好多。看来这种STMT模式并不适合SQL语句要反复重新更换的环境。否则Prepare的成本反而更加突出。(只能执行一次CGI的环境就不要用这个东西了。)
而只在第一次执行前使用Prepare的测试结果令人惊喜,普遍的速度提高在30%左右,这个速度的提升是非常鼓舞人心的。所以看来STMT的API非常适合数据库服务器SERVER类的开发。
另外要补充说明的是STMT的语句不使用查询Cache。