关于update in不走索引的:
首先select子查询形式是走索引的如下所示:
select * from acct_trans_payment where autopayflag='N' and objectno in(
select serialno from acct_loan where businessstatus='1' and accountingorgid='10080201')
执行计划如下:
然后select连接的形式:
select * from acct_trans_payment a,acct_loan b where a.objectno=b.serialno and a.autopayflag='N' and b.businessstatus='1' and b.accountingorgid='10080201';
执行计划如下:
至此可以看出来,select 的in子查询的形式优化器发生了内部转换,转换成了join链接的形式,提高的性能!
然而update的却没有自动转换成join链接的形式,如下所示:
update acct_trans_payment set autopayflag='Y' where autopayflag='N' and objectno in(
select serialno from acct_loan where businessstatus='1' and accountingorgid='10080201')
下文中有解释执行计划中的select_type中的dependent subquery的检索过程。
所以手动改写成join形式:
update acct_trans_payment a,acct_loan b set a.autopayflag='Y' where a.objectno=b.serialno and a.autopayflag='N' and b.businessstatus='1' and b.accountingorgid='10080201'
效率提高了。。。。
关于delete的优化过程:
delete from cfs.acct_trans_payment where serialno in(
select serialno from jd.jd_flow where repaymentstype='05'
);
首先我们来解释一下图中的dependent subquery是什么意思:手册上的解释是,子查询中的 jd.jd_flow表的select,取决于外面的查询。就这么一句话,其实它表达的意思是:子查询中的查询方式依赖于外部(cfs.acct_payment_log)的查询。换句话说就是jd.jd_flow表的检索方式依赖于cfs.acct_payment_log表的数据,如这里 cfs.acct_payment_log表得到的记录serialno (where serialno in)刚好可以被 jd.jd_flow表作为unique_subquery方式来获得它的相应的记录;换种写法如果此时cfs.acct_payment_log表扫描第一条记录得到的serialno为10001的话,那么后面子查询的语句就类似于这样的语句:
select serialno from jd.jd_flow where repaymentstype='05' and serialno='10001'。此时这个语句就会被优化拿来优化,变成了上面的子查询的执行计划,由于jd.jd_flow的主键是serialno,所以会走主键索引。
通过这个解释我们可以知道:全表扫描cfs.acct_payment_log表,将cfs.acct_payment_log的每条记录传递给jd.jd_flow表,jd.jd_flow表通过主键索引方式来获得记录判断自身的条件,则找到一个满足此查询的语句。
总结:当看到 select_type为dependent subquery的时候,就说明外表走的全表,然后把where value in 中的外表中的每个value值给子查询表,然后遍历结果!
当子查询结果比较小的时候可以先把子查询查出来,然后写成如下形式:
select * from cfs.acct_trans_payment where serialno in(
'101071256426871193705',
'101184648601257984005',
'101366238550600089605',
'101506423110987776005',
'101699991116782796905',
'101872867624796569705',
'99235027109713920005')
对应的执行计划:
那么当子查询结果集比较大的时候,改怎么优化呢?
一样借助连接的形式
delete
a
from cfs.acct_trans_payment a join jd.jd_flow b where a.serialno =b.serialno and b.repaymentstype='05'
等价于
delete from cfs.acct_trans_payment where serialno in(
select serialno from jd.jd_flow where repaymentstype='05'
);
如下是两个的执行计划,显然性能提升了不少!
又如:
delete
a ,b
from cfs.acct_trans_payment a join jd.jd_flow b where a.serialno =b.serialno and b.repaymentstype='05'
等价于
delete from cfs.acct_trans_payment where serialno in(
select serialno from jd.jd_flow where repaymentstype='05'
);
同时
delete from jd.jd_flow where repaymentstype='05' and serialno in (select serialno from
cfs.acct_trans_payment)
也就是说会把两个表的符合条件的都删除。。。。。
题外话:关于delete的join形式:
delete from left join
DELETE A FROM YSHA A LEFT JOIN YSHB B ON A.code=b.code WHERE b.code is NULL;
等同于
DELETE FROM YSHA WHERE NOT EXISTS(SELECT 1 FROM YSHB B WHERE YSHA.code=b.code );
注意delete的时候不允许起别名,如下会报错!!!!
delete from cfs.acct_trans_payment a where EXISTS ( select serialno from jd.jd_flow b where b.repaymentstype='05' and a.serialno=b.serialno );
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'a where EXISTS ( select serialno from jd.jd_flow b where b.repaymentstype='05' ' at line 1
可以需要这样:
delete from cfs.acct_trans_payment where EXISTS ( select serialno from jd.jd_flow b where b.repaymentstype='05' and cfs.acct_trans_payment.serialno=b.serialno )
总结
:update和delete都可以写成join的连接的形式,in子查询的形式执行计划中select_type中的dependent subquery的检索过程是外表是全表扫描,性能不佳,可以改写成join的连接的形式来提高性能。
mysql 关联更新删除不走索引优化
来源:这里教程网
时间:2026-03-01 11:39:11
作者:
编辑推荐:
- mysql 关联更新删除不走索引优化03-01
- Word文档图标显示不正常怎么办03-01
- pt-online-schema-change手记03-01
- MHA常用脚本简介03-01
- mysql MHA配置及三种切换方式演练03-01
- Simpo PDF Converter Ultimate PDF转换成Word转换器下载03-01
- 因为init_command 导致的 mysql 5.6 主从连接失败的案例一则。03-01
- php读取mysql数据03-01
下一篇:
相关推荐
-
雷神推出 MIX PRO II 迷你主机:基于 Ultra 200H,玻璃上盖 + ARGB 灯效
2 月 9 日消息,雷神 (THUNDEROBOT) 现已宣布推出基于英
-
制造商 Musnap 推出彩色墨水屏电纸书 Ocean C:支持手写笔、第三方安卓应用
2 月 10 日消息,制造商 Musnap 现已在海外推出一款 Oce
热文推荐
- MySQL:MGR 学习(2):Write set(写集合)的写入过程
MySQL:MGR 学习(2):Write set(写集合)的写入过程
26-03-01 - mysql 关联更新删除不走索引优化
mysql 关联更新删除不走索引优化
26-03-01 - php读取mysql数据
php读取mysql数据
26-03-01 - MySQL5.6 PERFORMANCE_SCHEMA 说明
MySQL5.6 PERFORMANCE_SCHEMA 说明
26-03-01 - 3DSMAX结合PS打造漂亮草地艺术字教程
3DSMAX结合PS打造漂亮草地艺术字教程
26-03-01 - 3DSMAX制作双12震撼来袭立体字
3DSMAX制作双12震撼来袭立体字
26-03-01 - 3ds max解析人体建模实例教程
3ds max解析人体建模实例教程
26-03-01 - 3Ds Max制作游戏中的CG人物教程
3Ds Max制作游戏中的CG人物教程
26-03-01 - CentOS系统更新升级完整指南(手把手教你安全高效地升级CentOS系统)
- 3DSMAX制作逼真的电脑耳机教程
3DSMAX制作逼真的电脑耳机教程
26-03-01
