首页 文章

我在一个表中有一百万行 . 出于性能原因,我决定使用union而不是in子句 . 这是真的吗?

提问于
浏览
1

我们在一个表中有一百万行 .

我们的选择:

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 回答

  • 3

    如果 column1, column2 上有一个唯一索引 - 按此顺序 - 那么带有 union 的版本肯定会利用索引 . 如评论中所述,您应该使用 union all 而不是 union . 这消除了删除重复项的步骤(即使没有重复项) . 这将是一些索引查找操作,应该非常快 .

    Oracle是否根据需要使用第一个版本的索引有点开放:

    where column1 in ('a', 'b', 'c', 'd') and column2 = 'abc'
    

    在这种情况下,大多数数据库不会以最佳方式使用索引 . 如果数据库使用了索引,它将使用 column1 lookups的索引,然后扫描索引,将值与 column2 进行比较 . Oracle可能会有一些额外的智能,可以在这里有效地使用索引 .

    但是,很容易解决问题 . 如果 column2, column1 上有索引,那么该索引将用于 where 子句 .

  • 1

    谁告诉你切换?他们是否提供了一些证据表明第二种方法在您的数据环境中实际上更有效?

    除非您的统计数据严重不正确或者有更多进展,否则我发现 UNION 方法不太可能比 IN 更有效 . 如果要打破查询,使用 UNION ALL 将比使用 UNION 更有效,因为它不会强制额外的排序来检查和消除(不存在的)重复行 . 假设有一个相对较新的Oracle版本,我希望优化器能够在内部将 UNION ALL 查询重写为 IN .

    但是,鉴于您有相关的表,您应该能够评估实际环境中两个选项的实际性能 . 您应该能够看到一种方法是否始终优于另一种方法,是否一个方法的逻辑I / O比另一方方法更少,等等 . 您还应该能够确定这两个查询是否实际生成了不同的计划 . 如果 UNION ALL 方法更有效,我使用 IN 语句找到更有效的计划 .

  • 0

    只是为了提供另一种选择,该声明可以写成:

    select * from tableA where (column1 = "a" and column2 = "abc")
    or (column1 = "b" and column2 = "abc") 
    or (column1 = "c" and column2 = "abc") 
    or (column1 = "d" and column2 = "abc") ;
    

相关问题