MySQL优化之绑定变量

既安全又高效

原理

从MySQL4.1版本开始,就支持服务器端的绑定变量(prepared statement)。

当创建一个绑定变量SQL时,客户端向服务器发送一个SQL语句的原型。服务器端接收到这个SQL语句后,解析并存储这个SQL语句的部分执行计划,返回给客户端一个SQL语句处理句柄。以后每次执行这类查询,客户端都指定使用这个句柄。

优势

  1. 可以更高效地执行大量的重复语句:
    • 在服务器端只需要解析一次SQL语句
    • 在服务器端某些优化项的工作只需要执行一次,因为它会缓存一部分的执行计划
    • 以二进制的方式只发送参数和句柄,比起每次都发送ASC2码文本效率更高
    • 仅仅是参数——而不是整个查询语句——需要发送到服务器端,所以网络开销会更小
    • MySQL在存储参数的时候,直接将其存放到缓存中,不再需要在内存中多次复制
  2. 绑定变量相对也更安全。无须在应用程序中处理转义,一则更简单了,二则也大大减少了SQL注入和攻击的风险
  3. 最主要的用途就是在存储过程中使用,构建并执行“动态”的SQL语句

限制

  • 绑定变量是会话级别的,所以连接之间不能共用绑定变量句柄
  • 在5.1版本之前,绑定变量的SQL是不能使用查询缓存的
  • 并不是所有的时候使用绑定变量都能获得更好的性能
  • 如果总是忘记释放绑定变量资源,则在服务器端很容易发生资源“泄漏”
  • 有些操作,比如BEGIN,无法在绑定变量中完成

实现

  1. 客户端模拟的绑定变量:客户端的驱动程序接收一个带参数的SQL,再将指定的值带入其中,最后将完整的查询发送给服务器端。
  2. 服务器端的绑定变量:客户端使用特殊的二进制协议将带参数的字符串发送到服务器端,然后使用二进制协议将具体的参数值发送给服务器端并执行。
  3. SQL接口的绑定变量:客户端先发送一个带参数的字符串到服务器端,这类似于使用PREPARE的SQL语句,然后发送设置参数的SQL,最后使用EXECUTE来执行SQL。所有这些都是使用普通的文本传输协议。