我有一个相当复杂的 SQL 查询,涉及从大量联接返回大约 20 列,用于填充 UI 中的结果网格。它还使用几个 CTE 来预过滤结果。我已经包含了下面查询的近似值(我已经注释掉了修复性能的行)
随着数据库中数据量的增加,查询性能大幅下降,主表“Contract”中只有大约 2500 行。
通过实验,我发现仅通过删除最后的顺序和偏移获取,性能就从大约 30 秒缩短到仅 1 秒!
order by 1 OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY
Run Code Online (Sandbox Code Playgroud)
这对我来说毫无意义。最后一行应该非常便宜,即使 OFFSET 为零也是免费的,那么为什么它会增加我的查询时间 29 秒呢?
为了保持 SQL 的相同功能,我对其进行了调整,以便首先选择 #TEMP,然后对临时表执行上述 order-offset-fetch,然后删除临时表。这将在大约 2-3 秒内完成。
我的“优化”感觉很错误,肯定有更明智的方法来达到相同的速度吗?
我还没有针对更大的数据集对此进行广泛测试,这本质上是目前恢复性能的快速修复。我怀疑随着数据大小的增长它是否会有效。
除了主键上的聚集索引之外,表上没有任何索引。查询执行计划似乎没有显示任何主要瓶颈,但我不是解释它的专家。
WITH tableOfAllContractIdsThatMatchRequiredStatus(contractId)
AS (
SELECT DISTINCT c.id
FROM contract c
INNER JOIN site s ON s.ContractId = c.id
INNER JOIN SiteSupply ss ON ss.SiteId = s.id AND ss.status != 'Draft'
WHERE
ISNULL(s.Deleted, '0') = 0
AND ss.status …Run Code Online (Sandbox Code Playgroud)