从PL / SQL插入临时表GTT非常慢

时间:2013-04-12 18:28:12

标签: sql performance oracle sql-tuning

我有一个从SQL执行时执行很棒的查询。

它是表和查询之间的连接。这两个表都有接近4个月的记录。 我试图提供提示的doc表上有位图索引。当我从蟾蜍看到时,解释计划确实表明他们正在帮助加入。

我提供了2个其他提示,看看它们是否有帮助,可以看出。一个用于直接路径APPEND,另一个用于利用pda上的现有BTree索引。

当从SQL运行替换变量的查询时,结果是即时的,但过程中的相同查询需要8秒或更长时间。

除了DBA尚未提出的程序计划之外,如果有任何明显的错过我可能会想到什么?提前谢谢。

 
     INSERT                                                           /*+ APPEND */
          INTO  tmp_search_gross_docs (document_id,
                                       last_name,
                                       first_name,
                                       person_doc_association_id,
                                       association_date)
       SELECT                 /*+INDEX(pda IDX_DOC_PDOC_DOCID ) USE_NL(pda doc) */
             pda.document_id,
              last_name,
              first_name,
              person_doc_association_id,
              association_date
         FROM   pda,
              (SELECT /*+INDEX_COMBINE(attr IDX_BMP_SEARCH_FN,IDX_BMP_SEARCH_LN)*/
                      document_id, last_name, first_name
                 FROM doc attr
                WHERE first_name LIKE l_first_name OR last_name LIKE l_last_name) doc
        WHERE pda.document_id = doc.document_id;
                         ) doc
                 WHERE pda.document_id = doc.document_id;

  

EXPLAIN计划(来自Toad的绑定变量)

INSERT STATEMENT ALL_ROWSCost:1,086,010 Bytes:15,309,420基数:364,510
    11 LOAD AS SELECT TMP_SEARCH_GROSS_DOCS
        10按索引表的访问权限表PDA成本:3字节:20基数:1
            9 NESTED LOOPS费用:1,086,010字节:15,309,420基数:364,510
                7 INDEX ROWID TABLE ATTR的表访问费用:23,893字节:8,019,220基数:364,510
                    6 BITMAP转换为ROWIDS
                        5 BITMAP或
                            2 BITMAP MERGE
                                1 BITMAP INDEX RANGE SCAN INDEX(BITMAP)IDX_BMP_SEARCH_FN                             4 BITMAP MERGE
                                3 BITMAP INDEX RANGE SCAN INDEX(BITMAP)IDX_BMP_SEARCH_LN                 8 INDEX RANGE SCAN INDEX IDX_PDA_EXP_DOC成本:2基数:1

基数364,510似乎已关闭,因为该表包含3738562行,而对于WHERE中的列的替换值,计数仅为8892。

但同样,这个计划至少告诉我正确的索引正在被使用,并且从蟾蜍编辑器中运行得非常快。

PL / SQL的实际计划仍然无法使用。

不确定这是否会增加一些有价值的信息。但是思想会编辑。感谢

3 个答案:

答案 0 :(得分:2)

首先,我不认为插入带有追加的GTT有任何逻辑。我可能是错的,但是从我所知道的旁边绕过缓冲区缓存并直接写入文件,它写在高水位线以上,并且在提交之前不允许查询。 GTT不在常规数据文件上 - 它位于临时文件上,并且在提交时被截断(默认设置)。

我认为如果您在查询后不需要操作数据,请考虑将ref光标返回给应用程序。它基本上是一样的 - 很多DAL层都以这种方式实现。

如果您仍然需要GTT,我会检查我的临时文件分配,包括大小和实际磁盘 - 您的DBA可能已将它们放在不同的设备上。

答案 1 :(得分:1)

你可能会研究一些事情。

  1. 与GTT表无关。 就像你说的那样,在nologging中创建表格,插入时使用insert append hint进行直接路径加载。

  2. 此外,如果您看到Toad的结果,可能会对查询速度产生误解。像toad这样的软件会自动添加提示以获取前50/100/200行,因此查询可能看起来运行得更快。您是否尝试过最后一条记录(网格中的“>”图标)并查看获取最后一行所需的时间?

  3. 如果不能看到计划,就无法调整查询甚至编写好的代码。如果它是一个更大的过程,您可以查看DBMS_PROFILER之类的内容。如果您确定这是导致问题的声明,您可以从SQL跟踪或解释计划开始。

答案 2 :(得分:0)

Adaptive cursor sharing does not apply to LIKE predicates.

如果您的程序首先使用%等参数执行,则Oracle无法对谓词使用某些索引访问方法。甲骨文无法听从你的提示,并建立了一个对%非常好的计划,但对其他一切都很糟糕。

一种可能的解决方案是强制Oracle始终对您的查询进行硬解析。我已经使用过这个解决方案,正如Dion Cho所解释的那样 this OTN thread

dbms_stats.set_table_stats('schema','DOC',num_rows=>null,no_invalidate=>false);

硬解析将使用额外的CPU资源,但希望更好的计划将弥补差异。此解决方案将导致其他不相关的查询需要进行硬解析。您可能希望查看引用的线程中提到的其他一些解决方案。

此外,您的INDEX_COMBINE提示可能不正确。索引之间不应该有逗号。但是,提示语法记录很少,提示解析器通常会“部分”工作。您的提示可能被评估为等效的 /*+INDEX_COMBINE(attr)*/,可能会或可能不会按您希望的方式运作。没有计划,你永远不会知道。

有充分的理由避免提示,特别是如果您无法方便地访问解释计划。