暂无图片
暂无图片
6
暂无图片
暂无图片
暂无图片

MySQL PREPARE预处理

原创 CuiHulong 2021-09-01
2501
MySQL PREPARE预处理技术意义在于,是为了减轻服务器压力的一种技术。

就是说绝大多数情况下,某需求某一条SQL语句可能会被反复调用执行,或者每次执行的时候只有个别的值不同。
比如:

  • SELECT的 WHERE子句值不同;
  • UPDATE的 SET子句值不同;
  • INSERT的 VALUES值不同;
    如果每次都需要经过上面的词法语义解析、语句优化、制定执行计划等,则效率就明显下降。

1.预处理

MySQL提供了对服务器端准备语句的支持,就叫预处理。

这种支持利用了高效的客户机/服务器二进制协议,使用带有参数值占位符的预编译语句有以下好处:

  • 减少每次执行语句时解析语句的开销。通常,数据库应用程序处理大量几乎相同的语句,只对子句中的字面值或变量值进行更改,例如用于查询和删除的WHERE、用于更新的SET和用于插入的values。
  • 防止SQL注入攻击。参数值可以包含未转义的SQL引号和分隔符。
预处理接口

1.应用程序中的预处理语句
可以通过客户端编程接口使用服务器端准备好的语句,包括用于C程序的MySQL C API客户端库,用于Java程序的MySQL Connector/J,以及用于使用。NET技术的程序的MySQL Connector/NET。例如,C API提供了一组函数调用,这些函数调用构成了它的预编译语句API

2.SQL脚本中的准备语句
还有一个用于预处理语句的替代SQL接口。但不需要编程,在SQL级别直接可用,可以在任何可以将SQL语句发送到要执行的服务器的程序中使用它,例如mysql客户端程序。

2.预处理应用方式

预处理语句的SQL语法基于三个SQL语句:

  • PREPARE语句准备执行。
  • EXECUTE执行一条预处理语句。
  • DEALLOCATE PREPARE释放一个预处理语句。

A.例子:

预处理语句无法跨SESSION操作:

mysql>CREATE TABLE `t1` ( `id` int NOT NULL, NAME varchar(20), KEY `idx_id` (`id`) ) ENGINE=InnoDB ; mysql>INSERT INTO t1(id,name) values(1,'A'),(2,'B'),(3,'C'),(4,'D'),(5,'E'),(6,'F'); #设定预处理语句 mysql>PREPARE stmt1 FROM 'SELECT * FROM t1 WHERE id=? '; #设置传递变量 mysql>SET @a = 8; #执行语句 mysql>EXECUTE stmt1 USING @a; #释放预处理语句 mysql>DEALLOCATE PREPAR stmt1;
复制

B.预处理对执行计划变化跟踪

通过观察status指标Select_scan(执行全表搜索查询的数量)变化判断是否会受到数据量变更的影响。
image.png
预处理sql语句随着数据量的变化执行计划也在变更。

C.存储过程包含预处理

预处理语句在存储的例程中创建预处理语句,则在存储的例程结束时不会释放该语句。

DELIMITER // DROP PROCEDURE IF EXISTS proc_prepared; CREATE PROCEDURE proc_prepared() BEGIN DECLARE a INT; DECLARE i INT; PREPARE stmt1 FROM 'SELECT * FROM t1 WHERE id>? '; SET @a = 5; EXECUTE stmt1 USING @a; END // DELIMITER ; call proc_prepared();
复制

存储过程之后单独调用预处理语句,返回结果集:说明预处理没有销毁

SET @a = 5; EXECUTE stmt1 USING @a; +----+------+ | id | NAME | +----+------+ | 6 | F | 。。。
复制

D.通过profile 查看解析语句的开销

通过profile各种语句执行时间,解析语句花费的时间都在0.01秒以内。可以忽略不计。
所以目前在预处理方面上没有发现明显的优势。
image.png

3.预处理使用情况

目前对于MySQL是使用预处理判断方式:

mysql > show variables like '%prepare%'; +------------------------------------------------------+-------+ | Variable_name | Value | +------------------------------------------------------+-------+ | max_prepared_stmt_count | 16382 | | performance_schema_max_prepared_statements_instances | -1 | +------------------------------------------------------+-------+ 2 rows in set (0.00 sec) mysql > show global status like '%prepare%'; +---------------------------------------------+-------+ | Variable_name | Value | +---------------------------------------------+-------+ | Com_prepare_sql | 0 | | Com_stmt_prepare | 0 | | Com_xa_prepare | 0 | | Com_stmt_reprepare | 0 | | Handler_prepare | 0 | | Performance_schema_prepared_statements_lost | 0 | | Prepared_stmt_count | 0 | +---------------------------------------------+-------+ 7 rows in set (0.00 sec)
复制

从官网提供材料没有视图可以查看,目前想到的方式是,通过tcpdump拦截一下流量, 分析预处理 语句是否使用 关键字。

4.总结

预编译初始的作用:

  • 提高效率:事先解析、检查、编译等工作。
  • 提高安全性:预防SQL注入

局限性和实际效果:

  • 预处理因为局限在session级别,现在无法体现真正的价值。因为mysql GA版本没有线程池概念,每个链接就是每个session
  • 解析编译语句的开销 基本对于mysql环境来说忽略不计
  • 执行计划也是随着数据量而变化的。

从局限性和实际效果来看,目前没有发挥应有的功能。不适合声场环境中使用。
image.png

以查看,目前想到的方式是,可能要拦截一下流量,tcpdump 分析预处理 语句是否使用 关键字。

最后修改时间:2024-03-06 14:01:52
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论

目录
  • MySQL PREPARE预处理技术意义在于,是为了减轻服务器压力的一种技术。
  • 1.预处理
    • MySQL提供了对服务器端准备语句的支持,就叫预处理。
    • 预处理接口
  • 2.预处理应用方式
    • A.例子:
  • B.预处理对执行计划变化跟踪
  • C.存储过程包含预处理
  • D.通过profile 查看解析语句的开销
  • 3.预处理使用情况
  • 4.总结