签到成功

知道了

CNDBA社区CNDBA社区

MySQL SQL预处理(Prepared)

2021-08-20 10:07 1829 0 转载 MySQL
作者: dave

1. SQL 语句的执行处理

1.1、即时 SQL

一条 SQL 在 DB 接收到最终执行完毕返回,大致的过程如下:
  1. 词法和语义解析;
  2. 优化 SQL 语句,制定执行计划;
  3. 执行并返回结果;
  如上,一条 SQL 直接是走流程处理,一次编译,单次运行,此类普通语句被称作 Immediate Statements (即时 SQL)。http://www.cndba.cn/dave/article/4666

1.2、预处理 SQL

但是,绝大多数情况下,某需求某一条 SQL 语句可能会被反复调用执行,或者每次执行的时候只有个别的值不同(比如 select 的 where 子句值不同,update 的 set 子句值不同,insert 的 values 值不同)。如果每次都需要经过上面的词法语义解析、语句优化、制定执行计划等,则效率就明显不行了。http://www.cndba.cn/dave/article/4666

所谓预编译语句就是将此类 SQL 语句中的值用占位符替代,可以视为将 SQL 语句模板化或者说参数化,一般称这类语句叫Prepared Statements。http://www.cndba.cn/dave/article/4666

http://www.cndba.cn/dave/article/4666

预编译语句的优势在于归纳为:一次编译、多次运行,省去了解析优化等过程;此外预编译语句能防止 SQL 注入。

虽然可能是通过预处理 SQL 的方式一定程度的提高了效率,但是对于优化而言,最优的执行计划不是光靠 SQL 语句的模板化来实现的,往往还是需要通过具体值来预估出成本代价。

http://www.cndba.cn/dave/article/4666
http://www.cndba.cn/dave/article/4666http://www.cndba.cn/dave/article/4666
http://www.cndba.cn/dave/article/4666

预处理 SQL 使用注意点
1、stmt_name 作为 preparable_stmt 的接收者,唯一标识,不区分大小写。
2、preparable_stmt 语句中的 ? 是个占位符,所代表的是一个字符串,不需要将 ? 用引号包含起来。
3、定义一个已存在的 stmt_name ,原有的将被立即释放,类似于变量的重新赋值。
4、PREPARE stmt_name 的作用域是session级

可以通过 max_prepared_stmt_count 变量来控制全局最大的存储的预处理语句。http://www.cndba.cn/dave/article/4666

http://www.cndba.cn/dave/article/4666

mysql> show variables like 'max_prepared%';
+-------------------------+-------+
| Variable_name           | Value |
+-------------------------+-------+
| max_prepared_stmt_count | 16382 |
+-------------------------+-------+
1 row in set (0.00 sec)

预处理编译 SQL 是占用资源的,所以在使用后注意及时使用 DEALLOCATE PREPARE 释放资源,这是一个好习惯。

2. 预处理的实现

  1. 声明预处理:prepare 预处理名字 from ‘要执行的SQL语句’;
  2. 执行预处理:exec 预处理名字;
  3. 销毁预处理:drop prepare 预处理名字;
prepare select_student from 'select * from students';
execute select_student;
drop prepare select_student;

3. 预处理占位符

要预处理相似SQL语句的执行,需要用到占位符:?,预处理可以同时甚多个占位符

--声明带占位符的预处理
prepare select_student from 'select * from students where age between ? and ?';
--定义两个变量
set @min = 1;
set @max = 18;
--使用两个变量代替占位符执行SQL指令
execute select_student using @min,@max;
用户评论
* 以下用户言论只代表其个人观点,不代表CNDBA社区的观点或立场
dave

dave

关注

人的一生应该是这样度过的:当他回首往事的时候,他不会因为虚度年华而悔恨,也不会因为碌碌无为而羞耻;这样,在临死的时候,他就能够说:“我的整个生命和全部精力,都已经献给世界上最壮丽的事业....."

  • 2261
    原创
  • 3
    翻译
  • 578
    转载
  • 191
    评论
  • 访问:7967484次
  • 积分:4346
  • 等级:核心会员
  • 排名:第1名
精华文章
    最新问题
    查看更多+
    热门文章
      热门用户
      推荐用户
        Copyright © 2016 All Rights Reserved. Powered by CNDBA · 皖ICP备2022006297号-1·

        QQ交流群

        注册联系QQ