Oracle SQL查询性能,基于函数的索引

时间:2015-05-06 18:59:31

标签: oracle performance

我一直在尝试微调一个需要1.5小时的SQL查询来处理大约4,000个错误记录。运行时间随着行数的增加而增加。

我发现我的SQL中有一个实际导致问题的条件

AND (DECODE (aia.doc_sequence_value, 
               NULL, DECODE(aia.voucher_num, 
                              NULL, SUBSTR(aia.invoice_num, 1, 10), 
                              aia.voucher_num) , 
               aia.doc_sequence_value) ||'_' ||
     aila.line_number ||'_' ||
     aida.distribution_line_number ||'_' || 
     DECODE (aca.doc_sequence_value, 
               NULL, DECODE(aca.check_voucher_num, 
                              NULL, SUBSTR(aca.check_number, 1, 10), 
                              aca.check_voucher_num) , 
               aca.doc_sequence_value)) = " P_ID" 

(P_ID - 第一个游标sql的值) (请注意,这些是标准的Oracle Applications(ERP)发票表)

P_ID列来自登台表,该登台表的导出方式与上面的派生方式相同,并在第二个SQL中再次进行比较,以获取该记录的最新数据。 (基本上重新处理错误记录,P_ID的值类似于“999703_1_1_9995248”)

Q1)我可以在整个左侧推导中创建基于函数的索引吗?如果是这样,语法是什么。 Q2)在标准Oracle表上创建基于函数的索引是否可以或违反oracle标准规则? (不直接在桌子上创建) Q3)如果不是解决这个问题的最佳方法是什么?

2 个答案:

答案 0 :(得分:1)

广告1)根据您发布的SQL,您无法在此基础上创建基于函数的索引。原因是基于函数的索引必须是:

  1. 确定性 - 即索引定义中使用的函数必须始终为给定的输入参数返回相同的结果,并且
  2. 只能使用创建索引的表中的列。在您的情况下 - 基于您正在使用的别名 - 您有四个表格(aiaailaaidaaca)。
  3. Req#2无法为该表达式构建功能索引。

答案 1 :(得分:1)

简单地说,你不能在该表达式上放置基于函数的索引,因为输入值是从四个不同的表(或表别名)派生的。

您可能会看到的是物化视图,但这很难解决单个查询优化问题。

您可以调查分解该字符串“999703_1_1_9995248”并将相关部分应用于单独的表达式:

 DECODE(aia.doc_sequence_value, 
           NULL,
           DECODE(aia.voucher_num, 
                NULL, SUBSTR(aia.invoice_num, 1, 10), 
                aia.voucher_num) , 
           aia.doc_sequence_value)  = '999703' and
 aila.line_number                   = '1'      and
 aida.distribution_line_number      = '1'      and
 DECODE (aca.doc_sequence_value, 
           NULL,
           DECODE(aca.check_voucher_num, 
                NULL, SUBSTR(aca.check_number, 1, 10), 
                aca.check_voucher_num) , 
           aca.doc_sequence_value)) = '9995248'

然后你可以在表达式和列上使用索引。

您可以使用正则表达式或InStr()和SubStr()

的组合来分隔P_ID值的四个组件