查询是直接比较的快速,但没有与同列索引的表比较,但没有。
我有一个相当复杂的查询,如果提供的话,它与@EventId进行直接比较,并且因为它抓取了聚集索引行而快速查询。但是,有时我需要做一组这些事件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 Server不快捷布尔表达式。
其次,由于表变量已知由于不正确的统计和行计数而导致错误的执行计划。请参阅此essay on the difference between table variables and temporary tables,主题:基数和无栏统计。
这可能有助于在查询的结尾处添加以下query hint:
OPTION(RECOMPILE);
这是每次重新编译的计划,但如果你得到可怕的表现小额的编译时不非常重要。
如果您拥有可选筛选器,并且与@EventId
一致,那么还建议使用此查询提示。
它也可能有助于在@EventIds
表变量上定义Id
上的主键。这将允许索引查找而不是表扫描。
我的意思是OPTION(RECOMPILE),而不是WITH(RECOMPILE)(编辑)。 –
我确实把它放在最后,因为某种原因,它加速了并且把它拿出来了,它还是更快。世界发生了什么?它是否节省执行计划缓慢? –
我在这个SP中有相当多的查询参数。我应该像你说的那样使用重新编译吗? –
查看执行计划并告诉我们两个查询之间有什么区别。 –