【问题标题】:Optimizing Oracle Queries - functions in the where clause优化 Oracle 查询 - where 子句中的函数
【发布时间】:2019-03-20 14:18:47
【问题描述】:

我一次又一次地被告知优化查询的最佳方法是删除 where 子句中的函数。函数会导致全表扫描。所以我的问题是,鉴于这三个查询,为什么具有 where 子句(图表 C)中的函数的查询执行得最好——快两倍以上?

图表 A - with 中的文本大写,因此 where 子句中没有任何功能,但仍将 where 子句放在 select 中

With Code As (
Select owner,name,Upper(text) As text,line From all_source
)
select * from Code
Where text Like '%UPPER(%'
And owner='COMMISSIONS'

图表 B - 将 with 中的文本大写并尽可能多地过滤

With Code As (
Select owner,name,Upper(text) As text,line From all_source
Where owner='COMMISSIONS'
)
select * from Code
Where text Like '%UPPER(%'

图表 C - 没有 with 子句和 where 子句中的函数

select * from all_source
Where upper(text) Like '%UPPER(%'
And owner='COMMISSIONS'

【问题讨论】:

  • 我猜你在owner 上有一个索引,这三个的性能非常相似。
  • 为了正确回答您的问题,我们需要知道表 all_source 有哪些索引。如果没有这些信息,我们几乎无法猜测。
  • 例如,如果您创建以下索引,您的查询 #3 可能会更快:create index ix1 on all_source (owner, upper(text));。做起来看看效果如何。

标签: sql oracle indexing


【解决方案1】:

TL;DR -- 由于缓存,您的第三个查询可能运行得最快。在性能方面,它既不比其他两个好也不差。但它是最简单的,也是你应该使用的。

为什么具有 where 子句(图表 C)中的功能的那个性能最好?

在 Oracle 的优化器处理完之后,您的所有三个查询基本相同。如果第三个运行得更快,可能是因为在 ALL_SOURCE 视图下的表中存在正在使用的索引,因为您指定了 owner = 'COMMISSIONS'。使用索引访问的索引块和表块有资格存储在块缓冲区缓存中。您的第三个查询受益于前两个已经读取并缓存了它需要的一些数据。 (证明?再次运行第一个查询)。

更重要的是:“从 WHERE 子句中删除函数”并不是描述传统建议的准确方式。

传统建议的存在是为了帮助新的 Oracle 开发人员了解索引的局限性。

拿出你最喜欢的技术参考,然后转到后面的索引。使用它来查找以“so”开头的每个主题的主题和页码。索引很有帮助,对吧?现在使用索引查找以“r”结尾的主题和页码(类似的 Oracle 函数是“substr(topic,-1) = 'r'”)。该索引不再有用了。 Oracle 索引也受到同样的限制。

现在,您的技术参考文献的作者可以在后面创建第二个索引,根据他们的最后一个字母组织所有主题。如果他们这样做了,那么该索引对于我在上面给你的第二个练习非常有用。同样,Oracle 可以创建“基于函数”的索引来回答基于该函数的查询(例如 substr(topic,-1))。

但是,在没有预先存在的基于函数的索引的情况下,对列的函数进行过滤的查询不会从该列的索引中受益。这是一个概括(也有例外,例如“覆盖”索引),但它是一个很好的概括。

不过,这些都不是关于 WHERE 子句中的函数。您的所有三个查询都会阻止 Oracle 在TEXT 上使用索引。通过使用视图或WITH 子句来执行函数来避免“WHERE 子句中的函数”不会让您绕过 Oracle 索引的限制。

(除了:您在TEXT 列上使用LIKE 运算符这一事实是索引不起作用的另一个重要原因——请参阅Oracle Text 功能以获得更好的选项,例如CONTAINS 运算符)。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多