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子查询慢的问题的更多相关文章
- [慢查优化]慎用MySQL子查询,尤其是看到DEPENDENT SUBQUERY标记时
案例梳理时间:2013-9-25 写在前面的话: 在慢查优化1和2里都反复强调过 explain 的重要性,但有时候肉眼看不出 explain 结果如何指导优化,这时候还需要有一些其他基础知识的佐助, ...
- Mysql子查询、关联查询
mysql中update.delete.install尽量不要使用子查询 一.mysql查询的五种子句 where(条件查询).having(筛选).group by(分组).orde ...
- Mysql子查询IN中使用LIMIT
学习下Mysql子查询IN中使用LIMIT的方法. 这两天项目里出了一个问题,mysql LIMIT使用后报错. 需求是这样的,我有3张表,infor信息表,mconfig物料配置表,maaply物料 ...
- MySQL 子查询 EXISTS 和 NOT EXISTS(转)
MySQL EXISTS 和 NOT EXISTS 子查询 MySQL EXISTS 和 NOT EXISTS 子查询语法如下: SELECT ... FROM table WHERE EXISTS ...
- MySQL子查询,派生表和通用表达式
一:子查询 1.介绍 在另一个查询(外部查询)中嵌套另一个查询语句(内部查询),并使用内部查询的结果值作为外部查询条件. 2.子查询在where中 SELECT customerNumber, che ...
- MySQL子查询慢现象的解决
当你在用explain工具查看sql语句的执行计划时,若select_type 字段中出现“DEPENDENT SUBQUERY”时,你要注意了,你已经掉入了mysql子查询慢的“坑". 相 ...
- MySQL子查询有哪五种形式?
MySQL是一个关系型数据库管理系统,由瑞典MySQLAB公司开发,目前属于Oracle旗下产品.MySQL是最流行的关系型数据库管理系统之一,在web应用方面,MySQL是最好的RDBMS(Rela ...
- mysql子查询用法
mysql子查询用法 1 可以当值来用<pre>select id from hcyuyin_share where id=(select id from hcyuyin_share li ...
- MySQL 子查询(一)
源自MySQL 5.7 官方手册 13.2.10 Subquery Syntax 〇.MySQL子查询介绍 子查询指的是嵌套在某个语句中的SELECT语句. MySQL支持标准SQL所要求的所有子查询 ...
随机推荐
- 【原创】leetCodeOj --- Word Ladder II 解题报告 (迄今为止最痛苦的一道题)
原题地址: https://oj.leetcode.com/submissions/detail/19446353/ 题目内容: Given two words (start and end), an ...
- [2014 Regional]牡丹江 H Hierarchical Notation 做题记录
主妇:老年人谁是炮灰牡丹江,我们的团队只是做同步大赛 他决定开爆震H什么时候,A 5min 1Y.I在该限制后,纠结了很久30min+ 1Y,神继续承担各种位置卡D在,hpp见B我认为这是非常熟悉的研 ...
- Javascript设计模式系列一
定义类,方法赋值给prototype属性各种写法: 方法一: <script type="text/javascript"> ////定义Message类 var Me ...
- Apache与Tomcat整合(转)
一 Apache与Tomcat比较联系 apache支持静态页,tomcat支持动态的,比如servlet等. 一般使用apache+tomcat的话,apache只是作为一个转发,对jsp的处理是由 ...
- char *详细指针
我前段时间写的char*和char[]差额.今char*做一个更深入的了解 1:char像指针和其他指针,也定义一个地址,例如int*它定义了一个堆栈,4字节,char*之,现在写一段代码 #incl ...
- JFileChooser
http://www.cnblogs.com/dyllove98/archive/2012/03/05/2461895.html package swing.choose; import java.a ...
- UVa 11069 - A Graph Problem
题目:给你一个集合{1,2,..,n},计算子集的个数,子集的元素不能相邻且不能再插入元素. 分析:dp,动态规划.相邻元素间仅仅能相差3或者2. 动态方程:f(k)= f(k-2)+ f(k-3): ...
- 读书笔记之SQL注入漏洞和SQL调优
原文:读书笔记之SQL注入漏洞和SQL调优 最近读了程序员的SQL金典这本书,觉得里面的SQL注入漏洞和SQL调优总结得不错,下面简单讨论下SQL注入漏洞和SQL调优. 1. SQL注入漏洞 由于“' ...
- android--jenkins+gradle+android自动化构建apk步骤(转)
第一步,安装jenkins,这个网上教程挺多的. 第二步,下载并配置gradle.下载地址http://www.gradle.org/ 解压gradle至某路径下,如/usr/local/lib/gr ...
- aauto攫http数据
说明:灵巧使用上述数据的抓取网页简单的例子. 样例:想把某站点的数据抓回来.然后保存在数据库里边. 步骤:1.打开sql.new一个数据库Test.新建一个表test. 2.打开快手.准备抓数据,以这 ...