【问题标题】:How to avoid OR expansion?如何避免 OR 扩展?
【发布时间】:2020-06-24 04:30:53
【问题描述】:

如果在连接条件中使用OR运算符,如何优化以下查询以避免SQL调优方面的OR扩展?

SELECT t1.A, t2.B, t1.C, t1.D, t2.E 
   FROM t1 LEFT JOIN t2
   ON t1.A=t2.A OR t1.B=t2.C;

【问题讨论】:

  • 这个查询有什么问题?请参阅here 您应该发布的最低限度
  • 您好,这里,据我所知,使用OR运算符在性能方面并不是一件好事。所以我想学习如何在 SQL 调优方面避免 OR 扩展。
  • 您使用什么版本的 Oracle?这是相关的 - 检查select * from V$VERSION
  • 您还应该学会区分在谓词中使用 OROR 扩展。前者由您在编写查询时完成,后者由 Oracle 优化器通过 转换查询 完成,目的是帮助您,以防 OR 谓词 可能导致性能问题。

标签: oracle database-performance sqlperformance sql-tuning


【解决方案1】:

具有 OR 条件将忽略使用索引。因此,一旦您拥有以下索引 -

t1 (A, B)
t2 (A, C)

您可以尝试下面的带有 UNION ALL 子句的查询 -

SELECT t1.A, t2.B, t1.C, t1.D, t2.E 
FROM t1 LEFT JOIN t2 ON t1.A=t2.A
UNION ALL
SELECT t1.A, t2.B, t1.C, t1.D, t2.E
FROM t1 LEFT JOIN t2 ON t1.B=t2.C;

此查询将使用索引并且可能执行得更快。

【讨论】:

  • 有 OR 条件将忽略使用索引 - 你有那个来源吗?
  • or 转换为 union 是“或扩展”,这正是 OP 想要避免的。 blogs.oracle.com/optimizer/…
  • 一个非常粗略的经验法则是将 Or 替换为 Union 以避免表扫描。
  • 好吧,不管什么原因,OP都想避免它。
  • 您的回答有两次错误。首先,建议的查询返回不同结果(应该使用UNION而不是UNION ALL)。其次,索引用于访问基于访问谓词的少量行,这里所有行都连接,因此在这两种变体中都不会使用索引。 (忽略快速全索引扫描的选项)。
猜你喜欢
  • 2023-03-07
  • 2015-03-11
  • 2016-11-13
  • 2012-07-08
  • 2023-01-13
  • 2019-07-10
  • 2023-04-07
  • 1970-01-01
相关资源
最近更新 更多