您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

MySQL子查询慢现象的解决

2025/11/5 16:39:26发布13次查看
当你在用explain工具查看sql语句的执行计划时,若select_type 字段中出现ldquo;dependent subqueryrdquo;时,你要注意了,你已
当你在用explain工具查看sql语句的执行计划时,若select_type 字段中出现“dependent subquery”时,,你要注意了,你已经掉入了mysql子查询慢的“坑。
相关书籍:高性能mysql(第3版) 中文pdf带目录清晰版
下面我们来看一个具体的例子
有这样一条查询语句:
select gid,count(id) as count from shop_goods g1 where status =0 and gid in (select gid from shop_goods g2 where sid in  (1519066,1466114,1466110,1466102,1466071,1453929))group by gid;
用explain看了一下,出现关键字“dependent subquery”,意味着子查询的第一个select依赖外部的查询;
subquery:子查询中的第一个select;dependent subquery:子查询中的第一个select,取决于外面的查询 。
换句话说,就是 子查询对 g2 的查询方式依赖于外层 g1 的查询。它意味着两步:
第一步,mysql 根据 select gid,count(id) from shop_goods where status=0 group by gid; 得到一个大结果集 t1,其数据量为rows=850672 了;
第二步,上面的大结果集 t1 中的每一条记录,都将与子查询 sql 组成新的查询语句:select gid from shop_goods where sid in (15...blabla..29) and gid=%t1.gid%。等于说,子查询要执行85万次……即使这两步查询都用到了索引,但不慢才怪;
如此一来,子查询的执行效率居然受制于外层查询的记录数,那还不如拆成两个独立查询顺序执行呢。
对于此类语句一般的优化策略是拆成两个查询语句,你不想拆成两个独立查询的话,也可以与临时表join查询,:
你不想拆成两个独立查询的话,也可以与临时表联表查询,如下所示优化后的sql:
select g1.gid,count(1) from shop_goods g1,(select gid from shop_goods where sid in (1519066,1466114,1466110,1466102,1466071,1453929)) g2 where g1.status=0 and g1.gid=g2.gid group by g1.gid;
用explain看了一下,这次又有了一个新的关键字derived,意思是用于 from 子句里有子查询的情况。mysql 会递归执行这些子查询,把结果放在临时表里,然后再做join操作;
derived 的官方含义为:用于 from 子句里有子查询的情况。mysql 会递归执行这些子查询,把结果放在临时表里。
《高性能mysql》的第4.4节“mysql查询优化器的限制(limitations of the mysql query optimizer)”之第4.4.1小节“关联子查询(correlated subqueries)”也有类似的论述:mysql 在处理子查询时,会改写子查询。通常情况下,我们希望由内到外,先完成子查询的结果,然后再用子查询来驱动外查询的表,完成查询。
例如:select * from test where tid in(select fk_tid from sub_test where gid=10);通常我们会感性地认为该 sql 的执行顺序是:sub_test 表中根据 gid 取得 fk_tid(2,3,4,5,6)记录,然后再到 test 中,带入 tid=2,3,4,5,6,取得查询数据。
但是实际mysql的处理方式为:
select * from test where exists (select * from sub_test where gid=10 and sub_test.fk_tid=test.tid);
mysql 将会扫描 test 中所有数据,每条数据都将会传到子查询中与 sub_test 关联,子查询不会先被执行,所以如果 test 表很大的话,那么性能上将会出现问题。
--------------------------------------分割线 --------------------------------------
ubuntu 14.04下安装mysql
《mysql权威指南(原书第2版)》清晰中文扫描版 pdf
ubuntu 14.04 lts 安装 lnmp nginx\php5 (php-fpm)\mysql
ubuntu 14.04下搭建mysql主从服务器
ubuntu 12.04 lts 构建高可用分布式 mysql 集群
ubuntu 12.04下源代码安装mysql5.6以及python-mysqldb
mysql-5.5.38通用二进制安装
--------------------------------------分割线 --------------------------------------
本文永久更新链接地址:
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product