当前位置:网站首页>MySQL如何对SQL做prepare预处理(解决IN查询SQL预处理仅能查询出一条记录的问题)
MySQL如何对SQL做prepare预处理(解决IN查询SQL预处理仅能查询出一条记录的问题)
2022-07-29 12:20:00 【葬心啊】
一、前言/概述
本周同事问了我一个问题,SQL中如何使用占位符做预处理,为什么他用了prepare却没有生效;
1、prepare简介
多次执行一条 SQL 语句时,如果每次都处理该 SQL 语句,生成执行计划,必然会浪费一定的时间。
SQL预处理(Prepare),是一种特殊的 SQL 处理方式;预处理不会直接执行 SQL 语句,而是先将 SQL 语句编译,生成执行计划,然后通过 Execute 命令携带 SQL 参数执行 SQL 语句。
- Prepare 的使用十分广泛,绝大多数 ORM 框架都有 API 支持;
- Prepare 既可以提升 SQL 执行性能,还能防止 SQL 注入引发的安全问题;
- Prepare 虽然在每个数据库中的语法差异很大,但是一般情况下我们都不会手写 SQL,而是使用 ORM 框架来做;
2、prepare的由来?
从mysql服务器执行sql的过程来看,SQL执行过程包括以下阶段 词法分析->语法分析->语义分析->执行计划优化->执行。
词法分析->语法分析这两个阶段我们称之为硬解析。
- 词法分析识别sql中每个词;
- 语法分析解析SQL语句是否符合sql语法,并得到一棵语法树(Lex)。
对于只是参数不同,其他均相同的sql,它们执行时间不同但硬解析的时间是相同的。
而同一SQL随着查询数据的变化,多次查询执行时间可能不同,但硬解析的时间是不变的。所以对于sql执行时间较短,sql硬解析的时间占总执行时间的比率越高。
Prepare的出现就是为了优化硬解析的问题。
虽然Prepare在execute阶段可以节省硬解析的时间。但如果sql只执行一次,且以prepare的方式执行,那么sql执行需两次与服务器交互(Prepare和execute), 而以普通(非prepare)方式,只需要一次交互。这样使用prepare会带来额外的网络开销,得不偿失。
如果同一sql需要执行多次,比如:以prepare方式执行10次,那么只需要一次硬解析。这时候 额外的网络开销就显得微乎其微了;因此prepare更适用于频繁执行的SQL中。
二、prepare做IN查询
MySQL 预处理是一组 SQL 操作的集合,它没有固定的语法格式,但多数情况下会按照如下 3 个步骤使用:
- 使用PREPARE指令预定义 SQL 语句模板;
- 使用SET指令定义 SQL 参数;
- 使用EXECUTE指令携带参数执行 SQL 模板。
1、预处理IN查询时失效了!
SQL:
prepare myFun from 'select * from user where id IN (?)';
set @str='1,2';
execute myFun using @str;
上述SQL会做三件事:
- 创建预处理SQL(
myFun),要使用变量的地方 用表示; - 设置变量
@str; - 执行预处理SQL(
myFun),USING后面跟参数,如果存在多个参数(即多个占位符?)使用英文逗号,分隔;
SQL执行结果:
从SQL执行结果来看,发现预处理SQL没有完全生效,只查询出了一行记录;正常应该查出两行记录;
2、解决预处理IN查询失效问题
使用如下SQL替换:
prepare myFun from 'select * from user where FIND_IN_SET(id,?)';
set @str='1,2';
execute myFun using @str;
SQL执行结果(符合预期):
3、MyBatis和JDBC中的动态IN查询
mybatis支持in的动态sql查询,其入参可以是一个Collection,底层将Collection的内容构建成使用英文逗号,分隔的字符串;也可以是英文逗号,分隔的字符串。
而原生的jdbc中sql不支持IN直接针对单个占位符传入逗号拼接的字符串,例如in (‘001’, ‘002’),需要开发者根据传入参数的个数来个构建占位符的个数;
例如传入一个数组或List,{‘001’, ‘002’};需要构造的in为:in(, );
然后再通过PreparedStatement#setString()方法动态构建SQL语句,。
边栏推荐
- 什么是BOM
- Wu En 07 regularization of teacher machine learning course notes
- Based article 】 【 learn with Rust | Rust, variables and data types
- SQL clock 】 【 daily DAY 23 丨 reporting to the CEO job difficulty moderate 】 【
- IO流:节点流和处理流详细归纳。
- 【实用工具】Image Assistant下载指定页面的所有图片
- How much is the test environment, starting from the actual needs
- MLX90640 红外热成像仪测温传感器模块开发笔记(九)
- [GO语言基础] 一.为什么我要学习Golang以及GO语言入门普及
- es6箭头函数讲解
猜你喜欢

Chapter 6 c + + primer notes 】 【 function

Recursion - Eight Queens Problem
![[纯理论] FCOS](/img/a4/f4f28faf5764e1fdebd475e445e2b0.png)
[纯理论] FCOS

2.3 Insertion sort

【第三次自考】——总结

TiCDC synchronization delay problem

Interceptors and filters (3) @interface custom annotation interception

2.2 Selection sort

别再问我如何制作甘特图了!

Paddle frame experience evaluation and exchange meeting, the use experience of the product is up to you!
随机推荐
数组及其内存管理三问
365天挑战LeetCode1000题——Day 043 有效的正方形 数学
WPF 截图控件之绘制方框与椭圆(四) 「仿微信」
金仓数据库KingbaseES安全指南--6.8. SSPI身份验证
【day04】IDEA、方法
The adb for mysql in what platform for development
[WeChat applet] WXSS and global, page configuration
CSDN TOP1 "a virgo program ape" how to become a blogger, millions of fans writing
什么是BOM
Chapter 2 Summary
Bookkeeping APP: Xiaoha Bookkeeping 3 - Production of Login Page
SQL clock in daily DAY 23 丨 】 the number of students have different subjects to test difficulty simple 】 【
Wu En 07 regularization of teacher machine learning course notes
APP local number one-click login
IDEA 数据库插件Database Navigator 插件
MySql string splitting realizes the split function (field splitting, column switching, row switching)
【每日SQL打卡】DAY 25丨求团队人数【难度中等】
2022-07-29 Daily: The latest major progress of AlphaFold: complete almost all known protein structure predictions of more than 200 million, fully open
TiDB 操作实践 -- 备份与恢复
拦截器与过滤器(三)@interface自定义注解拦截