10195 计划同一个查询!

Ste*_*hen 3 performance sql-server execution-plan query-performance

所以,我运行了 BrentOzar 脚本,它为同一查询确定了 10195 个计划!!!查询如下:

SELECT * 
FROM [table1]
INNER JOIN [table2]
  ON [table1].[versionId] = [table2].[VersionId]
INNER JOIN [table3]
  ON [table2].[ContentId] = [table3].[nodeId]
INNER JOIN [table4]
  ON [table3].[nodeId] = [table4].[id]
WHERE ([table4].[nodeObjectType] = 'abcde123-fgh3-4ijk-8lmn-424f222332ff')
  AND ([table1].[published] = 0 
  AND [table1].[releaseDate] <= '2017-07-22 17:43:47')
  AND ([table1].[newest]=1)
ORDER BY [table2].[VersionDate] DESC, [table4].[sortOrder]
Run Code Online (Sandbox Code Playgroud)

所有 10195 个之间的唯一区别是日期字段(发布日期)。每个计划具有不同日期的值。

关于索引,以下适用:

  • 表 1:nodeid 和 versionid 上的 NC,versionId 上的 C
  • 表 2:版本 ID 上的 NC,ID 上的 C
  • 表 3:节点 ID 上的 NC,pk 上的 C
  • 表 4:nodeObjectType 上的 NC,parentID 上的 NC,ID 上的 C

任何人都知道解决这个问题的最佳方法是什么,因为它变得非常荒谬!

提前致谢!

Tar*_*zer 14

您可以设置强制参数化在数据库级别选项以避免此问题,但它确实有一个缺点,即查询现在可能会遇到参数嗅探问题。CPU 利用率应会因更改而降低。我咨询了一个 CPU 利用率非常高且每秒编译量非常高的系统。启用强制参数化将 CPU 利用率降低了约 50%。另一个系统的 CPU 利用率变化很小,因为它们的每秒编译量并不高。在这两种情况下,计划缓存大小都减少了,因为查询现在重用缓存中的计划,而不是每次都编译新的查询计划。

或者,您可以修改应用程序,使其通过参数化查询/准备好的语句而不是即席 SQL 发送。或者使用存储过程。