码迷,mamicode.com
首页 > 数据库 > 详细

mysql in子查询的优化

时间:2019-08-20 09:15:35      阅读:129      评论:0      收藏:0      [点我收藏+]

标签:需要   oba   导致   遇到   esc   中间   plain   其他   sql   

项目遇到一个MySQL查询特别慢的语句:

SELECT *
FROM (
    SELECT DISTINCT t.vc_date, t.c_bankno, t.vc_bankacco, t.vc_moneytype, t.en_totalbala

    FROM tbankaccobala t

    WHERE 1 = 1
        AND t.id IN (
            --   这个查询需要3s:
            SELECT SUBSTRING_INDEX(GROUP_CONCAT(id ORDER BY d_importtime DESC), ',', 1)
            FROM tbankaccobala
            GROUP BY vc_bankacco
        )
) t

这个语句导致前端页面10秒左右才有响应(但MySQL执行显示要4.6秒,phpMyAdmin也是10秒左右响应,为何?)

但如果把IN语句里面的内容改成下面这样,只在外层再加一个select,就只要0.006s:

            SELECT hhhh from(
                SELECT SUBSTRING_INDEX(GROUP_CONCAT(id ORDER BY d_importtime DESC), ',', 1) as hhhh
                FROM tbankaccobala
                GROUP BY vc_bankacco
            ) as sbstr
            -- 对IN的子查询做二次select,或者把IN改为JOIN都可以解决速度奇慢的问题

原语句空行处省略了一系列的其他表和 INNER JOIN 语句。一开始怀疑是多表的JOIN操作导致速度变慢,但删去JOIN变成上面这段注释掉的语句之后,速度依然非常慢,显示要3s,于是猜测 IN 才是导致速度变慢的主要因素,改后只要0.006s,啧…

EXPLAIN 未优化的语句:
技术图片
(相关子查询是使用外部查询中的值的子查询)

EXPLAIN 优化的语句:
技术图片

我的理解:优化前,子查询是相关子查询,对于外部产生的每个值,都要执行一次子查询;优化后,子查询不再是相关子查询,只需要执行一次子查询并缓存中间结果,外部查到的每个值去缓存的中间结果里比对一下就行了。

(有人说是能不能用索引的原因——这么说应该是不对的)

深入理解MySql子查询IN的执行和优化

mysql in子查询的优化

标签:需要   oba   导致   遇到   esc   中间   plain   其他   sql   

原文地址:https://www.cnblogs.com/dylanchu/p/11380723.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!