gpt4 book ai didi

sql - CASE 子句上的 ORDER BY 可以更快吗?

转载 作者:行者123 更新时间:2023-12-02 17:47:46 24 4
gpt4 key购买 nike

我正在从一个包含约 3.5 亿条记录的表格中选择结果,而且它的运行速度非常慢 - 大约 10 分钟。罪魁祸首似乎是 ORDER BY,就好像我将其删除查询只需要一点时间。这是要点:

SELECT TOP 100
(columns snipped)
FROM (
SELECT
CASE WHEN (e2.ID IS NULL) THEN
CAST(0 AS BIT) ELSE CAST(1 AS BIT) END AS RecordExists,
(columns snipped)
FROM dbo.Files AS e1
LEFT OUTER JOIN dbo.Records AS e2 ON e1.FID = e2.FID
) AS p1
ORDER BY p1.RecordExists

基本上,我根据文件 是否有相应的记录 对结果进行排序,因为那些不需要先处理。我可以使用 WHERE 子句运行两个查询,但如果可能,我宁愿在一个查询中执行。

有什么办法可以加快速度吗?

最佳答案

最终的问题是,在子查询中使用 CASE 会在 sargable使用的东西上引入 ORDER BY。方式。因此,必须首先对整个中间结果集进行排序以找到前 100 名 - 这是所有 350+ 百万条记录!2

在这种特殊情况下,将 CASE 移动到外部 SELECT 并使用 DESC 排序(首先放置 NULL 值,这意味着当前 RecordExists 中的“0”)应该可以解决问题1 .虽然这不是通用方法......但排序应该非常非常快 iff Files.ID 被索引。 (如果查询仍然很慢,请查阅查询计划以找出为什么 ORDER BY 使用索引。)

另一种选择可能是为 RecordExists(也被索引)包含一个持久计算列,它可以用作 ORDER BY 中的索引。

再一次,想法是 ORDER BY 作用于某些东西 sargable ,它只需要在索引内部按顺序读取(最多达到与外部限制匹配的所需记录数)并且即时订购 350 多万条记录:)

SQL Server 然后能够将此排序(和限制)向下 推送到子查询中,而不是等待子查询的中间结果集向上。根据正在订购的什么 查看查询计划差异。


1 示例:

SELECT TOP 100
-- If needed
CASE WHEN (p1.ID IS NULL) THEN
CAST(0 AS BIT) ELSE CAST(1 AS BIT) END AS RecordExists,
(columns snipped)
FROM (
SELECT
(columns snipped)
FROM dbo.Files AS e1
LEFT OUTER JOIN dbo.Records AS e2 ON e1.FID = e2.FID
) AS p1
-- Hopefully ID is indexed, DESC makes NULLs (!RecordExists) go first
ORDER BY p1.ID DESC

2 实际上,它似乎可以假设在前 100 个 0 之后停止而不进行完整排序.. 至少在一些极端的查询规划器优化下 在封闭的函数范围内,但这取决于何时在中间结果集中遇到 0(在前几千或直到数亿或从不?)。无论如何,我非常怀疑 SQL Server 说明了这种极端情况;也就是说,不要指望这种仍然不可搜索的行为。

关于sql - CASE 子句上的 ORDER BY 可以更快吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12521902/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com