直接比较查询速度快,但与 table 比较相同列索引时查询速度不快
Query is fast with direct comparison, but not with table comparison with same column index
我有一个相当复杂的查询,它与 @EventId 进行直接比较(如果提供的话)并且速度很快,因为它获取聚集索引行。但是,有时我必须做一组这样的Event ID,第二行几乎需要30秒才能运行。我认为它与查找主键的工作方式相同。它这么慢是有原因的吗?
DECLARE @EventIds TABLE(Id INT NOT NULL);
WHERE
(@EventId IS NULL OR (ev.Id = @EventId)) AND
(NOT EXISTS(SELECT 1 FROM @EventIds) OR ev.Id IN (SELECT * FROM @EventIds))
没有充分的理由使用表达式
NOT EXISTS(SELECT 1 FROM @EventIds) OR ev.Id IN (SELECT * FROM @EventIds)
第一个表达式,即使为真,也不排除对第二个表达式的求值,因为 SQL 服务器没有快捷方式布尔表达式。
其次,由于不正确的统计信息和行数,已知 table 变量会导致错误的执行计划。请参考此 essay on the difference between table variables and temporary tables,主题:Cardinality 和 无列统计信息。
在查询末尾添加以下 query hint 可能会有所帮助:
OPTION(RECOMPILE);
是的,这每次都会重新编译计划,但如果您的性能很糟糕,那么少量的额外编译时间并不重要。
如果您有可选的过滤器,如 @EventId
。
,也推荐使用此查询提示
在 @EventIds
table 变量上定义 Id
上的主键也可能有所帮助。这将允许索引查找而不是 table 扫描。
我有一个相当复杂的查询,它与 @EventId 进行直接比较(如果提供的话)并且速度很快,因为它获取聚集索引行。但是,有时我必须做一组这样的Event ID,第二行几乎需要30秒才能运行。我认为它与查找主键的工作方式相同。它这么慢是有原因的吗?
DECLARE @EventIds TABLE(Id INT NOT NULL);
WHERE
(@EventId IS NULL OR (ev.Id = @EventId)) AND
(NOT EXISTS(SELECT 1 FROM @EventIds) OR ev.Id IN (SELECT * FROM @EventIds))
没有充分的理由使用表达式
NOT EXISTS(SELECT 1 FROM @EventIds) OR ev.Id IN (SELECT * FROM @EventIds)
第一个表达式,即使为真,也不排除对第二个表达式的求值,因为 SQL 服务器没有快捷方式布尔表达式。
其次,由于不正确的统计信息和行数,已知 table 变量会导致错误的执行计划。请参考此 essay on the difference between table variables and temporary tables,主题:Cardinality 和 无列统计信息。
在查询末尾添加以下 query hint 可能会有所帮助:
OPTION(RECOMPILE);
是的,这每次都会重新编译计划,但如果您的性能很糟糕,那么少量的额外编译时间并不重要。
如果您有可选的过滤器,如 @EventId
。
在 @EventIds
table 变量上定义 Id
上的主键也可能有所帮助。这将允许索引查找而不是 table 扫描。