我有这样的功课和太多的时间在我的手上,所以我希望答案是完美的而不是正确的。这完全是理论上的,没有真正的数据库。我想知道,切换WHERE语句的位置是否会产生性能差异如下:
订单是一个订单表,其中订单号为主键。客户是以客户编号Cno为主键的客户表。 Cno是表Order中的外键。我的任务是制定一个选择语句,为我提供名为“Meier'”的客户的所有订单,名称是客户表的数据列。
我的第一个想法是使用外键连接表并使用名称
进行过滤SELECT O.*
FROM Order O, Customer C
WHERE O.Cno = C.Cno
AND C.Name = 'Meier';
我将此语句可视化以生成包含所有客户和订单数据的LARGE表,然后使用名称进行过滤。
然后我有了一个想法,我可能会制作中间表'较小以赢得一些性能,所以我认为我可能会减少首先获取订单的客户数量。我想到了这个:
SELECT O.*
FROM Customer C, Order O
WHERE C.Name = 'Meier'
AND O.Cno = C.Cno;
现在我看到'这个假想的中间表只包含客户的订单' Meier'并且不要再这么大了。
然后,我认为Oracle可能会自行优化所有这些,所以我不需要担心它。
这些查询的性能是否存在差异,只是因为两个where子句语句的顺序是相反的?
答案 0 :(得分:2)
顺序无关紧要,因为Oracle的优化器会查看所有WHERE子句,并找出满足该查询的最有效方法。
您也可以考虑让您的表统计信息保持最新,因为优化程序倾向于使用它们。
答案 1 :(得分:2)
您也可以执行类似
的操作SELECT O.*
FROM (select Cno from Customer where Name = 'Meier') C, Order O
WHERE O.Cno = C.Cno;
99,99%的执行方式是相同的,但你可以通过提示来影响它。例如
SELECT O.*
FROM (select /*+ materialize */ Cno from Customer where Name = 'Meier') C, Order O
WHERE O.Cno = C.Cno;
首先将客户分组到临时表中,然后将其与订单连接。当您有两个以上的表时,可以使用ORDERED提示。
SELECT /*+ ORDERED */ O.*
FROM Customer C, Order O, Some_other_table T
WHERE C.Name = 'Meier'
AND O.Cno = C.Cno
AND O.Cno = T.Cno;
总是首先将Customer连接到Order,然后将结果连接到Some_other_tables,而不管统计信息是什么,有时可能是陈旧的。