当你在用explain工具查看sql语句的运行计划时。若select_type 字段中出现“DEPENDENT SUBQUERY”时,你要注意了。你已经掉入了mysql子查询慢的“坑"。。。

以下我们来看一个详细的样例

有这样一条查询语句:

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看了一下。出现keyword“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看了一下,这次又有了一个新的keyword"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 表非常大的话,那么性能上将会出现故障。

版权声明:本文博主原创文章,博客,未经同意不得转载。

mysql子查询慢的问题的更多相关文章

  1. [慢查优化]慎用MySQL子查询,尤其是看到DEPENDENT SUBQUERY标记时

    案例梳理时间:2013-9-25 写在前面的话: 在慢查优化1和2里都反复强调过 explain 的重要性,但有时候肉眼看不出 explain 结果如何指导优化,这时候还需要有一些其他基础知识的佐助, ...

  2. Mysql子查询、关联查询

    mysql中update.delete.install尽量不要使用子查询 一.mysql查询的五种子句         where(条件查询).having(筛选).group by(分组).orde ...

  3. Mysql子查询IN中使用LIMIT

    学习下Mysql子查询IN中使用LIMIT的方法. 这两天项目里出了一个问题,mysql LIMIT使用后报错. 需求是这样的,我有3张表,infor信息表,mconfig物料配置表,maaply物料 ...

  4. MySQL 子查询 EXISTS 和 NOT EXISTS(转)

    MySQL EXISTS 和 NOT EXISTS 子查询 MySQL EXISTS 和 NOT EXISTS 子查询语法如下: SELECT ... FROM table WHERE EXISTS ...

  5. MySQL子查询,派生表和通用表达式

    一:子查询 1.介绍 在另一个查询(外部查询)中嵌套另一个查询语句(内部查询),并使用内部查询的结果值作为外部查询条件. 2.子查询在where中 SELECT customerNumber, che ...

  6. MySQL子查询慢现象的解决

    当你在用explain工具查看sql语句的执行计划时,若select_type 字段中出现“DEPENDENT SUBQUERY”时,你要注意了,你已经掉入了mysql子查询慢的“坑". 相 ...

  7. MySQL子查询有哪五种形式?

    MySQL是一个关系型数据库管理系统,由瑞典MySQLAB公司开发,目前属于Oracle旗下产品.MySQL是最流行的关系型数据库管理系统之一,在web应用方面,MySQL是最好的RDBMS(Rela ...

  8. mysql子查询用法

    mysql子查询用法 1 可以当值来用<pre>select id from hcyuyin_share where id=(select id from hcyuyin_share li ...

  9. MySQL 子查询(一)

    源自MySQL 5.7 官方手册 13.2.10 Subquery Syntax 〇.MySQL子查询介绍 子查询指的是嵌套在某个语句中的SELECT语句. MySQL支持标准SQL所要求的所有子查询 ...

随机推荐

  1. ubuntu 12.04安装经典的Gnome桌面

    这次介绍的是如何在ubuntu 12.04 中安装经典的 GNOME桌面,默认的 Ubuntu 12.04 默认unity桌面,一些用户不喜欢 Unity 桌面,所以想找回昔日的经典Gnome桌面. ...

  2. 9、Cocos2dx 3.0游戏开发找小三之工厂方法模式与对象传值

    重开发人员的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/27704153 工厂方法模式 工厂方法是程序设计中一个 ...

  3. QEMU-KVM自己主动创建虚拟机,以指定IP构造

    正在使用qemu不能指定创建虚拟机的过程IP住址,然而,在实际应用中,我们需要有一台虚拟机IP住址,不是人为的虚拟机操作系统配置. 于qemu虚拟机技术文档(http://qemu.weilnetz. ...

  4. APK 代码混淆

    # To enable ProGuard in your project, edit project.properties # to define the proguard.config proper ...

  5. 自定义DB连接池实现

    实现一个简单的数据库连接池 1,连接池接口 package dbsource; import java.sql.Connection; import java.sql.SQLException; /* ...

  6. Best Time to Buy and Sell Stock I,II,III [leetcode]

    Best Time to Buy and Sell Stock I 你只能一个操作:维修preMin拍摄前最少发生值 代码例如以下: int maxProfit(vector<int> & ...

  7. JAVA设计模式(08):结构化-飞锤(Flyweight)

    当前咱们国家正在大力倡导构建和谐社会,当中一个非常重要的组成部分就是建设资源节约型社会,"浪费可耻,节俭光荣". 在软件系统中,有时候也会存在资源浪费的情况,比如在计算机内存中存储 ...

  8. Oracle生成查询包括对应于所有数据表记录语句中指定的字段名

    应用:已知的字段名,表中的所有数据的查询数据库中包含的所有数据表的字段名 操作方法:指定字段名,用户数据库表,它可以执行以下查询 --Oracle生成查询包括对应于所有数据表记录语句中指定的字段名 d ...

  9. PHP redis操作类 个人总结

    <pre name="code" class="php"><span style="font-size:18px;"> ...

  10. iphone6 plus有什么办法

    在苹果9月9号最新的秋季公布会上苹果官方公布了最新的iPhone6 plus,可能非常多朋友不知道plus是什么意思,这样命名有什么特殊的意义呢?本次Ly经典家居小编就为大家带来这方面的具体解答,一起 ...