【发布时间】:2017-05-14 17:44:00
【问题描述】:
我有一些复杂的查询,其中包含许多表的连接。由于复杂,很难进行真正的查询。
有点像
select t1.id, t2.id, t1.name, t2.name
from table1 t1, table2 t2
left join table3 t3 ON t2.id = t3.id
where t2.id = t1.ref_id
and t1.ref_id IN ('id1', 'id2', 'id3', 'id4', 'id5', ...)
我发现,如果我在 IN 子句中只有 4 个或更少的值,例如 t1.ref_id IN ('id1', 'id2', 'id3', 'id4'),它的工作速度非常快(16 毫秒)。如果我只添加一个 id 并将其设置为 5 像这样 t1.ref_id IN ('id1', 'id2', 'id3', 'id4', 'id5') 执行时间增加到 40 倍并变为 600 ms。
我在 SQL Server 2014 上得到它。
看起来有一些参数可以控制这种行为。我在另一个 SQL 服务器(SQL Server 2008)中尝试了这个查询,但找不到任何限制。
我的问题:是否有任何参数可以控制这种行为?或者如何将这个奇怪的限制增加到 50。
我只想将它增加到 30-50 而不是 4。当然我不想创建具有成百上千个值的 IN 子句。
更新1
对不起,我忘了把 t3.name 放到 select 里,不然看起来 t3 我不需要了:
select t1.id, t2.id, t1.name, t2.name, t3.name
from table1 t1, table2 t2
left join table3 t3 ON t2.id = t3.id
where t2.id = t1.ref_id
and t1.ref_id IN ('id1', 'id2', 'id3', 'id4', 'id5', ...)
更新2
看来我找到了原因。问题不在于 IN 内的物品数量。后来我用少于 4 个 id(即使是 1 个)重现了这个问题。发生这种情况是因为某些 id 未在 t1.ref_id 中显示。当有 t1.ref_id 中不存在的 id 时,它很快,当我添加 t1.ref_id 中确实存在的 id 时,它变慢了。在我之前的示例中,t1.ref_id 中没有显示 id1 - id4 并且显示了 id5。这就是为什么当我添加 id5 时它会变慢。即使我只在 IN 子句中放入 1 个 id (id5),它也会变得很慢。最后索引 t1.ref_id 解决了这个问题。 4 或 5 个 id 周围没有魔法。在我的具体例子中这只是一个巧合。
【问题讨论】:
-
您是否在 t1.ref_id 上创建了索引?
-
您在缩小差异方面做得很好。现在比较慢版本和快版本之间的查询计划。你看到了什么。按 CTRL-L 查看查询计划。
-
你不应该混合隐式和显式连接语法,你应该重写为显式语法。它是 1992 年以来的 ANSI 标准!此查询是存储过程的一部分吗?加
OPTION(RECOMPILE)有帮助吗? -
@Nick.McDermaid 是的,谢谢。我现在就在做。
-
@Zlelik 我明白你的意思,你现在可以停止对我开枪了
标签: sql sql-server sqlperformance in-clause