She*_*llz 3 performance sql-server sql-server-2016 query-performance
我有这个需要 10 多秒才能运行的存储过程。它向应用程序返回一个数据集(文件列表)。有关如何加快速度的任何建议?
有关计划的详细信息。看起来计划中的查询 14 占批处理的 98%。查询 14 中的排序占查询 14 的 62%。
我使用的是 SQL Server 2016。估计的查询计划。
这是实际的计划。花了 5 分钟。和 21 秒运行。
第一个插入语句的实际计划揭示了一些您应该改进的地方:
OPTION (RECOMPILE)
向这个查询添加一个提示。这将允许优化器在考虑变量的运行时值的情况下生成计划。这应该会大大简化计划。ClientID, UploadCompleteDttm
作为前导键。这将提供所需的排序顺序,并在@startdate_local
不为空时允许查找。索引还应包括FileName, FileUploadID, ProcessErrorText
以避免查找。一个示例索引定义是:
CREATE INDEX IndexName
ON fileManager.FileUploads (ClientID, UploadCompleteDttm)
INCLUDE (FileName, FileUploadID, ProcessErrorText);
Run Code Online (Sandbox Code Playgroud)FilesReceived上的聚集索引扫描看起来非常昂贵。测试了 55 亿行(通过多次扫描)以返回大约 5,000 行。这个成本被残差谓词很好地隐藏了(如Sentry One Plan Explorer 所示):
向以为键的FilesReceived添加索引FileUploadID
。如果该索引已存在,并且在应用了此处列出的先前步骤后扫描仍保留在实际执行计划中FORCESEEK
,请在FilesReceived引用上使用提示。你也可以试试OPTION (USE HINT ('DISABLE_OPTIMIZER_ROWGOAL'));
。
跳出我的问题部分是:
这对应于代码:
(select count(1)
from fileManager.FilesReceived fr
join fileManager.Tracking t on fr.FilesReceivedID = t.FilesReceivedID
where parentfileid = z.FilesReceivedID) as 'HasChildren'
Run Code Online (Sandbox Code Playgroud)
其余的执行计划相当大,但看起来并不太可怕。OPTION (RECOMPILE)
出于与第一次查询相同的原因,我仍会再试一次。
如果这本身不能充分提高性能:我将从查询中删除上面显示的代码片段,将结果行(给出的示例中只有 5,239)持久化在一个单独的临时表中,然后在HasChildren
单独的步骤中找到该值。我还将重写 finalINSERT
以使用显式TOP (5)
子句而不是使用SET ROWCOUNT 5
.
确保FilesReceived表在 上有一个索引ParentFileId
。
归档时间: |
|
查看次数: |
421 次 |
最近记录: |