SQL - NOT IN内部的查询需要比完整查询更长的时间吗?

Ale*_*lex 5 sql oracle

我在我的SQL查询中使用NOT IN.

例如:

select columnA 
from table1
where columnA not in (
select columnB
from table2)
Run Code Online (Sandbox Code Playgroud)

这部分查询怎么可能

select columnB
from table2
Run Code Online (Sandbox Code Playgroud)

需要30秒才能完成,但上面的整个查询需要0.1秒才能完成?不应该完整的查询需要30秒+?

顺便说一下,两个查询都返回有效结果.

谢谢!

评论的答案

是因为第二个查询实际上没有完成,但只返回了第一个'x'行(从一个非常大的表中?)

不,查询在30秒后完成,而不是返回多行(例如50).

但@Aleksandar想知道为什么这个性能杀手的问题是如此之快.

我的观点确切

另外,从table2中选择distinct columnB需要执行多长时间?

实际上,原始查询是"选择不同的...

Dav*_*sta 4

您似乎认为您的主要查询意味着以下步骤:

(1)  Run the subquery
(2)  Check each row in table1 against the result set from the subquery.
Run Code Online (Sandbox Code Playgroud)

因此,您认为单独运行子查询一定比运行整个查询花费更少的时间。

但 SQL 不是一种过程语言,查询的结构并不一定意味着执行查询所遵循的步骤。

正如 Guffa 回答的那样,优化器将提出(它认为的)执行每个查询的最佳计划。通过查看查询,这些执行计划并不总是显而易见的,并且在某些情况下确实可能非常违反直觉。

我认为在这种情况下,优化器很可能提出了一种更快的方法来检查 table2 中是否存在某个值,而不是简单地一次查询所有 table2 。这可能是 Guffa 所展示的转换(尽管这仍然没有告诉您正在使用的确切执行计划)。

我猜想 table1 的行数明显少于 table2,并且 table2.columnB 上存在索引。因此,它所要做的就是从 table1 中获取行,然后探测每个值的索引以检查是否存在。但这只是一种可能。

此外,正如 Michael Buen 指出的那样,返回结果集大小的差异也会影响您感知的性能。我的直觉是,这对于执行计划差异来说是次要的,但它可能很重要。