Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle SQL查询性能,基于函数的索引_Oracle_Performance - Fatal编程技术网

Oracle 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),

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

我发现我的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应用程序(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!非常有用的信息!