哪个有效?查询子查询或连接表

Pat*_*iks 5 sql database oracle

以下是两个用于相同目的的查询示例(在此示例中,我希望对来自Patriks居住的同一城市的推销员进行优秀.)

select * 
from salesman 
where salesman.city = 
     ( select city 
       from salesman 
       where salesman_name='Patriks'
     );
Run Code Online (Sandbox Code Playgroud)

select s1.* 
from salesman s1,salesman s2 
where s1.city=s2.city 
  and s2.salesman_name='Patriks';
Run Code Online (Sandbox Code Playgroud)

哪个更好或更有效?为什么?(我知道这是一个很小的例子,但我想弄清楚,在复杂情况下这对于大数据库来说会很好.)

Daw*_*ica 5

我的经验是,在Oracle中,扁平查询(即具有连接的查询)通常比使用子选择的等效查询更有效.对于具有子选择的查询,似乎在更复杂的情况下,Oracle优化器找不到查询路径.

在SQL Server,DB2,Ingres和Sybase中,我的经验是没有区别 - 这些DBMS具有将找到相同查询路径的优化器,无论您使用的是扁平查询还是使用子查询的查询.

我没有其他DBMS的足够经验来评论这些.

但那只是我的经历.如果您针对特定查询或特定数据集找到不同的结果,我不会感到惊讶.最好的办法是尝试两种方法,看看哪种查询更适合您的情况.


cag*_*boy 5

一般的经验法则是:

如果使用子查询,则强制Oracle使用某个执行路径(即它必须先执行子查询才能执行外部查询)

如果您使用联接,Oracle可以自由选择它认为最有效的路径.

因此,我总是会在子查询上加入.因人而异.

  • 因为在获得内部位的结果之前,您无法处理外部位.(举个例子想起来了,比如x =(5*(4 + 2)).你要做的内(4 + 2),你可以做外乘法之前).注意,还有的优化器也许能有机会解决内部/外部结构,但根据我的经验,往往不是这种情况. (2认同)
  • 事实上,它并不总是意味着它确实存在. (2认同)
  • 我赞成了cagcowboy的答案,因为它比我的好.他/她至少给出了一个启发式方法来建议Oracle将会和不会找到哪些查询计划; 我无法做到(除了说Oracle不会找到所有查询计划).至于"为什么"Oracle以这种方式工作; 除了Oracle的设计师之外,谁能真正说出来? (2认同)