直接比较查询速度快,但与 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 扫描。