使用sql join" ON"使用" AND"的声明而不是" WHERE"

时间:2015-11-04 14:56:10

标签: sql oracle join

所以我想知道哪一个是性能最好的,如果使用AND在这里只是不好的做法。

比较以下两个查询结束:

使用" WHERE"最后:

select c.cust_last_name,
       o.order_total,
       oi.quantity
from   customers c 
       join orders o on (c.customer_id = o.customer_id)
       join order_items oi on (o.order_id = oi.order_id)
where  c.GENDER='M';

使用" AND"最后:

select c.cust_last_name,
       o.order_total,
       oi.quantity
from   customers c 
       join orders o on (c.customer_id = o.customer_id)
       join order_items oi on (o.order_id = oi.order_id and c.GENDER='M');

并且正在使用最后一个ON条件来检索与第一个查询完全相同的数据集。这样好吗?

3 个答案:

答案 0 :(得分:3)

在这种情况下,我怀疑它会对Oracle使用哪个版本的查询产生很大影响。您可以查看每个查询的解释计划进行检查。

但是,将public Blob foo(@RequestBody String id, @HeaderParam(value= "some_header") String someHeader) { return new Blob(); } 谓词移动到此处的连接条件是“安全的”,因为您正在进行内连接。如果您正在进行外连接,则会看到不同的结果,具体取决于该谓词是在where或join子句中。

答案 1 :(得分:1)

将条件放在WHERE子句或ON子句中没有区别。

但是,是的,您显示的不良做法,因为and c.GENDER='M'与从表order_items加入哪些记录无关。 ON子句中的条件应始终属于其表。

订单商品表上附加条件的示例是

join order_items oi on (o.order_id = oi.order_id and and oi.price > 50)

如果你想在ON子句或WHERE子句中看到这个,这或多或少是个人偏好的问题。你可以争辩说你在他们的订单ID上加入了表格,然后只有保持结果的价格高于50,所以加入只在ID上。或者你可以说你加入订单商品的价格>这两个陈述在语义上都是正确的。

但是,在ON子句中始终拥有表中的所有条件是一个好习惯。当你改变

inner join order_items oi on (o.order_id = oi.order_id)
where oi.price > 50

left join order_items oi on (o.order_id = oi.order_id)
where oi.price > 50

这实际上仍然是一个内连接,因为外连接记录的价格为NULL,不符合您的WHERE子句条件,因此您在创建后立即删除记录:-)因此,由于其他连接类型,您必须将条件移动到ON子句。在那里拥有它不是更好吗?

答案 2 :(得分:1)

我认为除非您的表中有大量记录,否则性能上的差异并不显着。

第一种情况是首先根据内部联接获取所有相关记录,然后根据男性进行过滤。您正在加载其中一部分不相关(女性)然后过滤的所有记录。

在第二种情况下,根本不会收集不相关的记录,过滤是作为连接操作的一部分完成的。

我同意@Radu Gheorghiu,你可能想把c.GENDER ='M'的条件提高一级。