Oracle SQL查询性能,基于函数的索引
我一直在尝试微调SQL查询,该查询需要1.5小时来处理大约4000条错误记录。运行时间随着行数的增加而增加 我发现我的SQL中有一个条件实际上导致了这个问题Oracle SQL查询性能,基于函数的索引,oracle,performance,Oracle,Performance,我一直在尝试微调SQL查询,该查询需要1.5小时来处理大约4000条错误记录。运行时间随着行数的增加而增加 我发现我的SQL中有一个条件实际上导致了这个问题 AND (DECODE (aia.doc_sequence_value, NULL, DECODE(aia.voucher_num, NULL, SUBSTR(aia.invoice_num, 1, 10),
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应用程序(ERP)发票表)
p_ID列来自staging表,该表以与上述派生相同的方式派生,并在第二个SQL中再次进行比较,以获取该记录的最新数据。(基本上是重新处理错误记录,P_ID的值类似于“999703_1_1_9995248”)
Q1)我可以基于整个左侧派生创建基于函数的索引吗?如果是,语法是什么。
Q2)在标准oracle表上创建基于函数的索引是可以的还是违反oracle标准规则的?(不直接在表本身上创建)
问题3)如果不是,那么解决此问题的最佳方法是什么?Ad 1)基于您发布的SQL,您不能基于该SQL创建基于函数的索引。原因是基于函数的索引必须是:
aia
,aila
,aida
,aca
)李>
Req#2使得不可能为该表达式构建函数索引。简单地说,不可以在该表达式上放置基于函数的索引,因为输入值来自四个不同的表(或表别名) 您可能会看到一个具体化的视图,但这是一个很大的问题,可能很难用它来解决单个查询优化问题 您可以研究分解字符串“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值的四个组成部分。您是否先对查询运行解释计划和跟踪?可能还有其他方法来构造查询。另外,请注意,说“有点紧急”并不会给你带来某种“优先帮助”。什么是
“P\u ID”
?VARCHAR2
通常看起来像“P\u ID”
。此外:如果将三个\uu
串联起来,表达式如何等于'P\u ID'
?基于函数的索引可能有助于提高性能。。。。但是更多的信息有助于找到最好的方法:)谢谢老程序员!我有解释计划,但我确实知道确切的SQL条件(如上所述)需要时间,因此我猜我需要解决一个解决方案:使用上述ID创建新列以比较和获取唯一记录或其他……非常感谢David,非常好的想法,这很有帮助,但是直接在基表上创建基于函数的索引不符合Oracle标准吗?我想Oracle不支持它,请告诉我。您可以在基表上创建它们,从技术上讲,这是可行的。或者,可以使用表达式作为视图中的新列来查询放置在基表上的视图,并确保索引表达式与该表达式匹配。或者添加一个虚拟列并索引该列。如果你不能做到后者,那么试试其他的方法。Oracle支持没有问题,更重要的是可以轻松地在查询中指定正确的表达式。感谢您澄清npe!非常有用的信息!