2011-07-25 60 views
0

TableX的Oracle SQL IN语句:是否按顺序执行?

number doc 
number item 
number parentItem 

随着数据:

1, 1000, 0 
1, 1010, 1000 
1, 1020, 1000 
1, 2000, 0 
1, 2010, 2000 


TableY

number doc 
number item 
varchar2(16) SomeData 

随着数据:

1, 1000, "1000 Data" 
1, 2000, "2000 Data" 


我用下面的SQL查询来从TableY

select x.doc, x.item, y.SomeData from TableX x 
join TableY y 
on y.doc = x.doc and y.item IN (x.item, x.ParentItem) 

获得 “SomeData” 应该结果是在:

1, 1000, "1000 Data" 
1, 1010, "1000 Data" 
1, 1020, "1000 Data" 
1, 2000, "2000 Data" 
1, 2010, "2000 Data" 

我的问题是:是对IN-声明评估顺序,或者这取决于Oracle采取的路径?


编辑 我的意思是,当有在TableY一个项目从TableX的(如1000),一个条目将这个值可以首先在使用JOIN或将ParentItem首先使用? 或者只有在项目上的JOIN失败时才会对ParentItem执行JOIN操作?

+1

我不确定在这种情况下,“顺序评估”到底是什么意思。你问IN语句是否保证在连接条件之后被应用?您是否在IN子句中询问两个值是否存在短路评估?或者你在问别的吗? –

+1

如果您关心的是结果集的排序,您可以保证使用ORDER BY进行排序。否则,评估顺序应该不重要。 –

+0

见[编辑]注释 –

回答

4

通常,使用数据库时,除非指定一个数据库,否则没有顺序。我认为IN总是检查整个列表,而不是在发现匹配时发生短路,但是不能保证列表将被处理的顺序(如果它检查整个列表则不重要)。


根据修改后的问题:

Oracle无法创建基于行包含的内容执行计划,使优化器将制定一个计划,以最有效的方式查找两列可能。这个计划将取决于你的表格大小和你创建的索引。

一次处理表几乎总是更快,所以优化器可能会选择一个路径,在该路径中,它可以轻松地检查两个列,而不是一次一个检查列。这意味着,除非它有更好的途径,否则可能会进行全表扫描。有一点实验表明,即使索引覆盖了两列,优化器也会选择全表扫描。

有趣的是,这似乎是少数情况下可能更好地将两列分别索引的情况之一。如果两列上都有单独的索引,看起来优化器将扫描两个索引,然后使用bitmap or从每个结果集中获取唯一的rowid集。

这里需要说明的是,我的研究是在大型桌子上使用高度人造的场景完成的。您应该以最简单,最容易阅读(和维护)的方式构建查询,然后测试它的实际性能并查看它的解释计划。只有在确定存在性能问题(或者可能存在性能问题)时,才应该担心找到另一种更有效(但可能不那么明了)的方式来编写查询。一般来说,如果你有一个经过深思熟虑的sargable查询,优化器将在挑选最有效的路径方面做得很好。

0

评估顺序无关紧要。 IN声明仅仅是说y.item = x.item OR y.item = x.ParentItem OR ...的简短方法。