mysql in子查询的优化

Posted dylanchu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql in子查询的优化相关的知识,希望对你有一定的参考价值。

项目遇到一个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子查询的优化的主要内容,如果未能解决你的问题,请参考以下文章

如何优化 MySQL 中的 IN 子查询?

mysql in子查询的优化

mysql 子查询 优化

那个mysql 子查询和连接查询 一般常用哪个 谁效率高些

mysql中主查询和子查询关系是啥?

MySQL中IN子查询会导致无法使用索引