Jer*_*eir 7 performance sql-server sql-server-2016
我有一个总是过滤状态的查询,这些方式中的一种是否比另一种方式有性能优势?
(这是在即席查询的上下文中。UserStatus 的数据类型是 int)
...
AND UserStatus = 1
...
Run Code Online (Sandbox Code Playgroud)
或者
DECLARE @userStatus int = 1
...
AND UserStatus = @userStatus
...
Run Code Online (Sandbox Code Playgroud)
(ps 请不要谈论参数和文字在值未知/变化时有何不同,这是一个不同的话题)
Zan*_*ane 11
好吧,假设您正在谈论从 SSMS 中的查询运行的局部变量,因为它没有另外指定。即使您使用与AND UserStatus = @userStatus文字中相同的值,
AND UserStatus = 1由于基数估计的生成方式,您的执行计划也会有所不同。
当您使用文字值时,SQL Server 将查看该表的直方图并查看该值在范围键内的位置。对此收集的估计将导致两种情况之一。
HISTOGRAM DIRECT HIT本质上,这意味着RANGE_HI_KEY查询中该特定文字值有一个(直方图中任何步骤的上列值)值,因此估计值将匹配直方图中EQ_ROWS(值等于 的行数)的数量RANGE_HI_KEY. 这意味着您的估计将是根据上次更新统计信息与该值匹配的行数。
HISTOGRAM INTRA-STEP HIT这是当值存在于两个RANGE_HI_KEY值之间的范围内时。当您的文字值在该范围之间时,它由RANGE_ROWS(两个直方图步骤之间的行数)、DINSTINCT_RANGE(该直方图步骤中不同值的数量)和AVG_RANGE_ROWS(RANGE_ROWS/ DISTINCT_RANGE_ROWS)计算得出,这将为您提供估计值。
但是,当您使用局部变量运行时,您将不再访问这些值的直方图,因为它们@Variable在运行时是未知的。
有关此主题的更多信息,我建议您阅读Joe Sack 的这份白皮书。
DENSITY VECTOR当没有特定的值时,SQL Server 会使用密度来确定为该谓词返回的估计行数。密度为 1/ 该列中不同值的数量。那么你的基数估计将是密度 * 表中的行数。
长话短说没有。即使您使用局部变量一遍又一遍地运行相同的值,您也不会得到相同的结果,原因在Kendra Little提供的链接 Eric 中进一步解释。
优化器知道字面值(因此它可以根据该值估计选择性)。
在执行时嗅探参数值(存储过程、函数)。后续执行可能具有其他一些值,对于这些值,先前编译的计划可能不是最佳的。
对于变量,优化器不知道该值。它可能能够查看密度(平均而言,对于某个值,我们有这么多行),或者它使用硬连线估计(例如 > 导致 10% 的选择性,或者无论那些受限制的百分比可能是什么) .
| 归档时间: |
|
| 查看次数: |
824 次 |
| 最近记录: |