我们在一个表中有一百万行 .
我们的选择:
select * from tableA where column1 in ("a", "b", "c", "d") and where column2 = "abc";
我们在column1和column2上有唯一的索引 .
有人告诉我swtich:
select * from tableA where column1 = "a" and column2 = "abc"
union
select * from tableA where column1 = "b" and column2 = "abc"
union
select * from tableA where column1 = "c" and column2 = "abc"
union
select * from tableA where column1 = "d" and column2 = "abc";
在IN子句中我们可以有1到100个不同的值 . 因此,最好使用IN子句运行一个语句或运行100语句并执行union .
3 回答
如果
column1, column2
上有一个唯一索引 - 按此顺序 - 那么带有union
的版本肯定会利用索引 . 如评论中所述,您应该使用union all
而不是union
. 这消除了删除重复项的步骤(即使没有重复项) . 这将是一些索引查找操作,应该非常快 .Oracle是否根据需要使用第一个版本的索引有点开放:
在这种情况下,大多数数据库不会以最佳方式使用索引 . 如果数据库使用了索引,它将使用
column1
lookups的索引,然后扫描索引,将值与column2
进行比较 . Oracle可能会有一些额外的智能,可以在这里有效地使用索引 .但是,很容易解决问题 . 如果
column2, column1
上有索引,那么该索引将用于where
子句 .谁告诉你切换?他们是否提供了一些证据表明第二种方法在您的数据环境中实际上更有效?
除非您的统计数据严重不正确或者有更多进展,否则我发现
UNION
方法不太可能比IN
更有效 . 如果要打破查询,使用UNION ALL
将比使用UNION
更有效,因为它不会强制额外的排序来检查和消除(不存在的)重复行 . 假设有一个相对较新的Oracle版本,我希望优化器能够在内部将UNION ALL
查询重写为IN
.但是,鉴于您有相关的表,您应该能够评估实际环境中两个选项的实际性能 . 您应该能够看到一种方法是否始终优于另一种方法,是否一个方法的逻辑I / O比另一方方法更少,等等 . 您还应该能够确定这两个查询是否实际生成了不同的计划 . 如果
UNION ALL
方法更有效,我使用IN
语句找到更有效的计划 .只是为了提供另一种选择,该声明可以写成: