使用过滤器对一个结果进行ORDER BY语句的性能调整

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用过滤器对一个结果进行ORDER BY语句的性能调整相关的知识,希望对你有一定的参考价值。

我有以下简单查询:

SELECT TOP 1 message 
FROM Log l 
WHERE l.id_fk = '##Guid##'
AND l.id_category IN ('Category 1', 'Category 2') 
ORDER BY l.timestamp DESC

[大型日志表的执行时间很长,timestamp上没有非聚集的降序索引,因为必须首先对完整列表进行排序才能获得前1个条目。

是否有可能通过语句摆脱顺序,或者完全是创建索引的最佳解决方案?

答案

我认为最快的方法是这个更复杂的查询:

SELECT TOP (1) message
FROM ((SELECT TOP 1 l.message, l.timestamp
       FROM Log l 
       WHERE l.id_fk = '##Guid##' AND
             l.id_category = 'Category 1'
       ORDER BY l.timestamp DESC
      ) UNION ALL
      (SELECT TOP 1 l.message, l.timestamp
       FROM Log l 
       WHERE l.id_fk = '##Guid##' AND
             l.id_category = 'Category 2'
       ORDER BY l.timestamp DESC
      ) 
     ) l
ORDER BY timestamp DESC

这可以利用log(id_fk, id_category, l.timestamp)上的索引。不幸的是,SQL无法将timestamp上的索引与IN一起使用。

另一答案

尝试一下:

SELECT TOP 1 message 
FROM (select l.timestamp,l.message
        FROM Log l 
        WHERE l.id_fk = '##Guid##'
        AND l.id_category IN ('Category 1', 'Category 2') 
        ) x
ORDER BY x.timestamp DESC

只是简单地写出来,基本上内部查询会将您的数据条件过滤到较小的集合中,然后命令得到前1个

另一答案

查询很好。您需要此索引:

 CREATE INDEX idx ON log (id_fk, id_category, timestamp DESC);

甚至是这个:

 CREATE INDEX idx ON log (id_fk, id_category, timestamp DESC, message);

因此可以快速查找这两个类别的最大时间戳。使用后一个索引,甚至不必读取表。

以上是关于使用过滤器对一个结果进行ORDER BY语句的性能调整的主要内容,如果未能解决你的问题,请参考以下文章

Hive中的Order by与关系型数据库中的order by语句的异同点

如何使用 SQL Order By 语句对结果进行排序,不区分大小写?

mysql中的select语句where条件group by ,having , order by,limit的顺序及用法

SQL的order by语句

mysql中“group by、having、order by、limit”的顺序及用法是啥?

mysql中“group by、having、order by、limit”的顺序及用法是啥?