【问题标题】:Oracle: function based index using dynamic valuesOracle:使用动态值的基于函数的索引
【发布时间】:2013-03-24 23:37:35
【问题描述】:

我有一个复杂的 SQL 查询。查询的一个简单部分如下所示:

Query 1:
SELECT *
  FROM table1 t1, table2 t2
 WHERE t1.number       = t2.number
   AND UPPER(t1.name)  = UPPER(t2.name)
   AND t1.prefix       = p_in_prefix;


Query 2:
SELECT *
  FROM table1 t1, table2 t2
 WHERE t1.number       = t2.number
   AND UPPER(t1.name)  = UPPER(p_in_prefix || t2.name)
   AND t1.prefix       = p_in_prefix;

我在 table1 上有基于函数的索引为 (number, UPPER(name))。我的 table2 上有基于函数的索引为 (number, UPPER(NAME))。 p_in_prefix 是一个输入参数(基本上是一个数字)。

由于这些索引,我的查询 1 运行效率很高。但查询 2 存在性能问题,如查询 2 中,'t2.name' 以 p_in_prefix 为前缀。

我无法为查询 2 创建基于函数的索引,因为 p_in_prefix 是一个输入参数,我在创建索引时不知道它可能包含哪些值。在这种情况下如何解决性能问题?任何提示/想法将不胜感激。如果您需要更多信息,请告诉我。 谢谢。

【问题讨论】:

  • p_in_prefix 中的值是否与 TABLE2 中的任何字段对应?它还显示 TABLE1.NAME 中的数据设置不正确 - 您有一个单独的 PREFIX 字段,但 PREFIX 似乎预先添加到 NAME 的某些值。您可以尝试将查询 2 重写为 SELECT * FROM table1 t1, table2 t2 WHERE t1.number = t2.number AND UPPER(t1.name) = UPPER(t1.prefix || t2.name) AND t1.prefix = p_in_prefix。不知道这能买多少钱,但值得一试。分享和享受。

标签: performance oracle function indexing dynamic-data


【解决方案1】:

使用AND UPPER(t1.name) = UPPER(p_in_prefix) || UPPER(t2.name)

由于您有一个基于函数的索引,如 UPPER(NAME)table2,因此您应该在查询中有一个具有相同表达式的操作数,以便使用基于函数的索引。

使用UPPER(p_in_prefix || t2.name) 将不会使用基于函数的索引,因为这与函数表达式UPPER(NAME) 不匹配。请注意,使用UPPER(t2.name) 不会导致任何问题,因为t2 只是一个列别名。

除此之外,您还可以在查询中传递优化器提示,以指示优化器使用索引。

有关更多信息,请阅读 Jason Price 的“Oracle 数据库 11g SQL”。

另请阅读 Oracle Docs herehere 以及优化器提示 here

【讨论】:

  • 亲爱的 Rachcha,我尝试了您建议的方式,但没有帮助。除了将前缀与名称分开外,我还添加了优化器提示,指定要使用的索引名称。但是性能仍然很差。另一件事是,t2 表有列前缀,但我不希望在 t2 上创建另一个索引,因为该表上的插入性能受到阻碍。
  • 您的一个大问题是您在运行时使用p_in_prefix 参数,因此您甚至无法在该表达式上创建单独的索引。您能否在问题中提出您的解释计划,以便每个人都能理解发生了什么? :)
猜你喜欢
  • 1970-01-01
  • 2019-06-05
  • 2017-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多