过去,周围有很多偏执狂IN
。特别是,我记得声称它可以与等效的WHERE EXISTS
. 这个说法仍然正确吗?或者现在是否保证在两个查询逻辑上相等的情况下总是给出相同的执行计划IN
?WHERE EXISTS
我正在谈论以下形式的查询
SELECT [...] FROM [FOO] WHERE [FOO_ID] IN (SELECT [FOO_ID] FROM [BAR])
-- Is logically equivalent to...
SELECT [...] FROM [FOO] WHERE EXISTS (SELECT 1 FROM [BAR] WHERE [BAR].[FOO_ID] = [FOO].[FOO_ID])
并不是说我没有谈论NOT IN
、NOT EXISTS
或使用多个IN
子句。
这个说法仍然正确,但它只是对长硬编码
IN
表达式列表的关注。问题主要在于额外的编译时间,尽管也可能导致奇怪的查询计划,因为它们被编译成许多OR
子句。您的示例有所不同:它使用
IN
子查询,该子查询在早期阶段转换为半连接,这类似于无论如何EXISTS
。编译时间应该几乎相同,并且您可以从这个小提琴中亲眼看到查询计划是相同的,无论表是否建立索引。是的,计划并不总是相同,但这通常是您获得新编译的结果,优化器无法在两个错误计划之间做出决定(您同样可以通过重新编译相同的查询来获得此结果)。如果子查询上有一个好的访问方法,那么计划通常是相同的。