Oracle SQL IN语句:这是按顺序执行的吗?

时间:2011-07-25 13:19:27

标签: sql oracle join sequential

TableX的

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

获取“SomeData”
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)

哪个应该导致:

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

我的问题是: IN-Statement 是按顺序评估的,还是这取决于Oracle采用的路径?


修改 我在TableY中为TableX中的项目(如1000)输入一个条目,这个值是首先在JOIN中使用还是首先使用ParentItem? 或者,只有当项目上的JOIN失败时,才会在ParentItem上进行JOIN操作?

2 个答案:

答案 0 :(得分:4)

通常,在使用数据库时,除非您指定一个,否则没有订单。我相信IN总是检查整个列表,而不是在找到匹配时进行短路,但是不能保证列表的处理顺序(不管它是否检查整个列表都很重要)。 / p>


根据您修改后的问题:

Oracle无法根据行包含的内容创建执行计划,因此优化程序将开发一个计划,以最有效的方式查找这两列。该计划将在很大程度上取决于您的表的大小和您创建的索引。

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

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

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

答案 1 :(得分:0)

评估顺序无关紧要。 IN语句只是说y.item = x.item OR y.item = x.ParentItem OR ...的简单方法。