我有一个从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的实际计划仍然无法使用。
不确定这是否会增加一些有价值的信息。但是思想会编辑。感谢
答案 0 :(得分:2)
首先,我不认为插入带有追加的GTT有任何逻辑。我可能是错的,但是从我所知道的旁边绕过缓冲区缓存并直接写入文件,它写在高水位线以上,并且在提交之前不允许查询。 GTT不在常规数据文件上 - 它位于临时文件上,并且在提交时被截断(默认设置)。
我认为如果您在查询后不需要操作数据,请考虑将ref光标返回给应用程序。它基本上是一样的 - 很多DAL层都以这种方式实现。
如果您仍然需要GTT,我会检查我的临时文件分配,包括大小和实际磁盘 - 您的DBA可能已将它们放在不同的设备上。
答案 1 :(得分:1)
你可能会研究一些事情。
与GTT表无关。 就像你说的那样,在nologging中创建表格,插入时使用insert append hint进行直接路径加载。
此外,如果您看到Toad的结果,可能会对查询速度产生误解。像toad这样的软件会自动添加提示以获取前50/100/200行,因此查询可能看起来运行得更快。您是否尝试过最后一条记录(网格中的“>”图标)并查看获取最后一行所需的时间?
如果不能看到计划,就无法调整查询甚至编写好的代码。如果它是一个更大的过程,您可以查看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)*/
,可能会或可能不会按您希望的方式运作。没有计划,你永远不会知道。
有充分的理由避免提示,特别是如果您无法方便地访问解释计划。