如何加快sql查询?

Posted

技术标签:

【中文标题】如何加快sql查询?【英文标题】:How to speed up the sql query? 【发布时间】:2020-07-18 00:54:10 【问题描述】:

我有一个 SQL 查询如下:

SELECT p.Id1,p.Id2,p.Id3 
FROM dataset1 p
WHERE p.Id2 IN (
    SELECT r.Id4 
    FROM dataset1 r 
    WHERE r.Id5=125 AND r.Id6>=100000000000000 AND r.Id6<1000000000000000
) 
ORDER BY p.Id1 DESC, p.Id2 DESC

但是,Id6 在这个范围内似乎有大量数据,因此计算需要相当长的时间。但我只有一小时来计算查询。因此,我想知道是否有人可以帮助我提高此查询的性能。

谢谢。

【问题讨论】:

请edit 在您的帖子中包含查询的执行计划 (EXPLAIN),以及有关表架构和索引的信息。当我们没有可用的详细信息时,很难帮助您优化查询。 请提供SHOW CREATE TABLE。如果涉及TEXT 列,则某些建议索引无效。 【参考方案1】:

由于过滤似乎是在r上完成的,所以先安排一下:

SELECT  p.Id1, p.Id2, p.Id3
    FROM  ( SELECT id4
       FROM dataset1 AS r
       WHERE  r.id5 = 125
         AND  r.Id6 >= 100000000000000
         AND  r.Id6 <  100000000000000 ) AS x
    JOIN dataset1 AS p  ON p.id2 = x.id4
    ORDER BY  p.Id1 DESC, p.Id2 DESC;

为此,这些索引应该是有益的:

INDEX(id5, id6, id4)   -- covering
INDEX(id2, id1, id3)   -- covering

您对id6 进行了“范围”测试,但范围为空。我认为这是一个错误。请不要过分简化查询;我们可能会给您不适用的建议。我假设范围确实是一个范围。

【讨论】:

【参考方案2】:

IN 在子查询返回大量数据时往往优化不佳。您可以尝试改用EXISTS

SELECT p.Id1, p.Id2, p.Id3 
FROM dataset1 p
WHERE EXISTS (
    SELECT 1
    FROM dataset1 r 
    WHERE 
        r.Id4 = p.Id2
        AND r.Id5 = 125 
        AND r.Id6 >= 100000000000000 
        AND r.Id6 <  100000000000000
) 
ORDER BY p.Id1 DESC, p.Id2 DESC

然后,考虑在(Id4, Id5, Id6) 上使用多列索引来加速子查询。这个想法是把更严格的标准放在第一位 - 所以很明显你希望 Id6 最后,但你可能想尝试反转前两列,看看是否有任何组合比另一个表现更好。

旁注:Id6 的下限和上限在您的查询中具有相同的值。我认为这是一个错字(否则您的查询将始终不返回任何行)。

【讨论】:

第 4 行中的“选择 1”是什么意思? @FrankQ - 模式是EXISTS ( SELECT 1 ... )1 不是很关键,因为其含义是“是否存在 any 行”。它很聪明,可以在不查找 all 行的情况下停止,就像在 JOIN 中发生的那样。【参考方案3】:

为了提高性能,不要使用内部查询。您也可以使用内部连接来获得所需的结果:

SELECT 
    p.Id1, p.Id2, p.Id3 
FROM 
    dataset1 p 
INNER JOIN 
    dataset1 r ON p.Id2 = r.Id4 
               AND r.Id5 = 125 
               AND r.Id6 >= 100000000000000 
               AND r.Id6 < 100000000000000
ORDER BY 
    p.Id1 DESC, p.Id2 DESC

【讨论】:

我的答案中提供了此配方的最佳索引。

以上是关于如何加快sql查询?的主要内容,如果未能解决你的问题,请参考以下文章

如何加快sql查询?

如何加快我在 sql 中的查询

如何加快sql子查询

如何加快 Oracle SQL Developer 上的 REGEX LEVEL 查询

如果 where 子句已经修复,如何加快 spark sql 过滤器查询?

加快我的 SQL 查询速度?它给出了执行超时错误