使用过滤器对一个结果进行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的顺序及用法