我在oracle中有一个查询导致OLAP系统的估计成本很高。估计的行数只有100K,但成本是一个巨大的数字。我想知道如何计算成本数量以及在哪种情况下会产生超高的估算成本?
执行计划:
17 TABLE ACCESS BY LOCAL INDEX ROWID /BIC/FZ3PM_C01
| ( Estim. Costs = 1,299,922,942,955,190 , Estim. #Rows = 104,711 )
| Pstart: 1 Pstop: 471
| Estim. CPU-Costs = 18,446,744,073,709,601,000 Estim. IO-Costs = 86,157,375,
|
--- 16 BITMAP CONVERSION TO ROWIDS
|
--- 15 BITMAP AND
|
|-- 7 BITMAP MERGE
| |
| --- 6 BITMAP KEY ITERATION
| |
| |-- 4 BUFFER SORT
| | |
| | ------3 TABLE ACCESS FULL /BIC/DZ3PM_C012
| | ( Estim. Costs = 4 , Estim. #Rows = 180 )
| | Estim. CPU-Costs = 1,093,126 Estim. IO-Costs = 4
| | Filter Predicates
| |
| ------5 BITMAP INDEX RANGE SCAN /BIC/FZ3PM_C01~050
| Pstart: 1 Pstop: 471
| Search Columns: 1
| Access Predicates
|
--- 14 BITMAP MERGE
|
--- 13 BITMAP KEY ITERATION
|
|-- 11 BUFFER SORT
| |
| --- 10 HASH JOIN
| | ( Estim. Costs = 2,492 , Estim. #Rows = 1,264,100 )
| | Estim. CPU-Costs = 801,483,146 Estim. IO-Costs = 2,407
| | Access Predicates
| |
| |-----8 TABLE ACCESS FULL /BI0/XMATERIAL
| | ( Estim. Costs = 1,470 , Estim. #Rows = 50,880 )
| | Estim. CPU-Costs = 403,451,418 Estim. IO-Costs = 1,427
| | Filter Predicates
| ------9 TABLE ACCESS FULL /BIC/DZ3PM_C011
| ( Estim. Costs = 1,007 , Estim. #Rows = 1,264,100 )
| Estim. CPU-Costs = 259,249,328 Estim. IO-Costs = 980
|
------12 BITMAP INDEX RANGE SCAN /BIC/FZ3PM_C01~040
Pstart: 1 Pstop: 471
Search Columns: 1
Access Predicates
答案 0 :(得分:3)
估计的100,000行是输出。可能需要做大量的工作来过滤大型数据集,甚至更多来总结大型数据集。也就是说,这些成本非常具有天价(即使数据库的数据大小需要400多个分区)
尝试执行解释计划,然后尝试SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY)
这提供了一个更易读的计划。您希望所有访问和过滤谓词都能看到它正在做什么,以及总结成本。
答案 1 :(得分:0)
位图索引转换表明您错过了一个好的索引,Oracle决定使用现有索引动态构建新的临时索引。它可能是非常繁重的操作,并且一旦执行查询就会删除构建的位图索引 - 因此在下次运行时不会重复使用。
您可以手动创建索引或在查询中添加一些提示以阻止位图转换吗? http://psoug.org/reference/hints.html - 提示的简短列表。更多Oracle文档。
我从100k行的子查询开始,用no_merge提示保护它(Oracle将在内部创建临时视图)并在此之后添加其他连接。如果查询优化器将继续混乱计划 - 强制更多提示,如index或use_nl等。
答案 2 :(得分:0)
问汤姆在估算成本方面有一个有用的主题:
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:40112614814595
答案 3 :(得分:0)
系统统计信息不良可能导致成本过高。
将select * from sys.aux_stats$;
的结果与this page上的说明进行比较。
我看到一些由11g错误引起的疯狂估计 - 收集工作负载统计数据可能完全失败,并将数字设置为几个数量级。