任何Oracle SQL调优Maven都可以帮助我理解下面的解释计划,以发现瓶颈。先谢谢你。
这个查询立即响应,但在理解解释计划后,我仍然在寻找对代码的潜在更改或修改。到目前为止,它的一切看起来很好,为我根据我的知识。我觉得这个返回一排的整体成本太高了。
--------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 25 | 10000 | 6105 (1)| 00:00:01 |
| 1 | SORT ORDER BY | | 25 | 10000 | 6105 (1)| 00:00:01 |
|* 2 | VIEW | | 25 | 10000 | 6104 (1)| 00:00:01 |
| 3 | WINDOW SORT | | 25 | 9625 | 6104 (1)| 00:00:01 |
| 4 | WINDOW SORT | | 25 | 9625 | 6104 (1)| 00:00:01 |
| 5 | WINDOW SORT | | 25 | 9625 | 6104 (1)| 00:00:01 |
| 6 | NESTED LOOPS ANTI | | 25 | 9625 | 6101 (1)| 00:00:01 |
| 7 | NESTED LOOPS OUTER | | 25 | 8800 | 6001 (1)| 00:00:01 |
| 8 | NESTED LOOPS OUTER | | 25 | 8125 | 5950 (1)| 00:00:01 |
| 9 | NESTED LOOPS OUTER | | 25 | 7675 | 5875 (1)| 00:00:01 |
| 10 | NESTED LOOPS OUTER | | 7 | 1862 | 5850 (1)| 00:00:01 |
| 11 | NESTED LOOPS OUTER | | 5 | 1200 | 5825 (1)| 00:00:01 |
| 12 | NESTED LOOPS OUTER | | 5 | 1165 | 5821 (1)| 00:00:01 |
| 13 | NESTED LOOPS OUTER | | 4 | 760 | 5807 (1)| 00:00:01 |
| 14 | NESTED LOOPS OUTER | | 4 | 684 | 5797 (1)| 00:00:01 |
| 15 | NESTED LOOPS OUTER | | 4 | 568 | 5793 (1)| 00:00:01 |
| 16 | NESTED LOOPS OUTER | | 4 | 540 | 5793 (1)| 00:00:01 |
| 17 | NESTED LOOPS OUTER | | 4 | 424 | 5789 (1)| 00:00:01 |
| 18 | NESTED LOOPS | | 4 | 396 | 5789 (1)| 00:00:01 |
| 19 | NESTED LOOPS | | 57 | 1995 | 5630 (1)| 00:00:01 |
| 20 | INLIST ITERATOR | | | | | |
|* 21 | INDEX RANGE SCAN | NU_LOV_ENTRY_1 | 3 | 36 | 3 (0)| 00:00:01 |
|* 22 | TABLE ACCESS BY INDEX ROWID BATCHED| PARTY | 22 | 506 | 1876 (1)| 00:00:01 |
|* 23 | INDEX RANGE SCAN | IDX_HOME_STORE_PARTY | 14838 | | 41 (0)| 00:00:01 |
|* 24 | TABLE ACCESS BY INDEX ROWID | PERSON | 1 | 64 | 3 (0)| 00:00:01 |
|* 25 | INDEX UNIQUE SCAN | XPKPERSON | 1 | | 2 (0)| 00:00:01 |
|* 26 | INDEX UNIQUE SCAN | XPKLOV_ENTRY | 1 | 7 | 0 (0)| 00:00:01 |
| 27 | TABLE ACCESS BY INDEX ROWID | TRANSLATION | 1 | 29 | 1 (0)| 00:00:01 |
|* 28 | INDEX UNIQUE SCAN | XPKTRANSLATION | 1 | | 0 (0)| 00:00:01 |
|* 29 | INDEX UNIQUE SCAN | XPKLOV_ENTRY | 1 | 7 | 0 (0)| 00:00:01 |
| 30 | TABLE ACCESS BY INDEX ROWID | TRANSLATION | 1 | 29 | 1 (0)| 00:00:01 |
|* 31 | INDEX UNIQUE SCAN | XPKTRANSLATION | 1 | | 0 (0)| 00:00:01 |
|* 32 | TABLE ACCESS BY INDEX ROWID BATCHED | PARTY_LEGAL_HOLD | 1 | 19 | 4 (0)| 00:00:01 |
|* 33 | INDEX RANGE SCAN | XIF3PARTY_LEGAL_HOLD | 1 | | 2 (0)| 00:00:01 |
|* 34 | TABLE ACCESS BY INDEX ROWID BATCHED | ADDRESS | 1 | 43 | 4 (0)| 00:00:01 |
|* 35 | INDEX RANGE SCAN | IDX$$_036C0004 | 1 | | 3 (0)| 00:00:01 |
| 36 | TABLE ACCESS BY INDEX ROWID | STATE_PROVINCE | 1 | 7 | 1 (0)| 00:00:01 |
|* 37 | INDEX UNIQUE SCAN | XPKSTATE_PROVINCE | 1 | | 0 (0)| 00:00:01 |
|* 38 | TABLE ACCESS BY INDEX ROWID BATCHED | PHONE | 1 | 26 | 5 (0)| 00:00:01 |
|* 39 | INDEX RANGE SCAN | IDX$$_036C0003_1 | 1 | | 3 (0)| 00:00:01 |
| 40 | TABLE ACCESS BY INDEX ROWID BATCHED | AGREEMENT_PARTY | 4 | 164 | 7 (0)| 00:00:01 |
|* 41 | INDEX RANGE SCAN | XIF2AGREEMENT_PARTY | 4 | | 3 (0)| 00:00:01 |
| 42 | TABLE ACCESS BY INDEX ROWID | AGREEMENT | 1 | 18 | 3 (0)| 00:00:01 |
|* 43 | INDEX UNIQUE SCAN | XPKAGREEMENT | 1 | | 2 (0)| 00:00:01 |
| 44 | TABLE ACCESS BY INDEX ROWID BATCHED | INSTALLMENT_NOTE | 1 | 27 | 3 (0)| 00:00:01 |
|* 45 | INDEX RANGE SCAN | IDX_INSTALLMENT_NOTE_AGR_ID | 1 | | 2 (0)| 00:00:01 |
|* 46 | TABLE ACCESS BY INDEX ROWID BATCHED | AGREEMENT_PARTY | 1 | 33 | 4 (0)| 00:00:01 |
|* 47 | INDEX RANGE SCAN | UQ_AGREEMENT_PARTY_1 | 1 | | 3 (0)| 00:00:01 |
字符串
1条答案
按热度按时间yhuiod9q1#
1.没有一个解释计划被认为是“错误的”。Oracle生成的每个计划都可能是正确的计划。重要的是它的假设您的数据是在目标或没有。只有在基于错误的数据假设生成计划时,该计划才会变为“错误”计划。因此,没有人能看到一个计划本身,并告诉你什么是错误的。
1.如果您的查询可以立即响应,需要修复什么?您的计划在末尾显示了一些WINDOW SORT,这意味着所有行都已经通过了它之前的嵌套循环步骤,并通过了排序,因此没有任何事情要做(例如,您具有良好吞吐量,而不仅仅是良好的响应)。
1.忽略COST。这没有任何意义- Oracle总是选择其计算成本最低的计划,但当其数据假设错误时,其计算将导致 * 不正确的 * 成本数字,通常(但不总是)导致糟糕的计划。如果你有一个糟糕的计划,你看到的成本是错误的,所以不应该给一个时刻的想法。相反,关注计划实际上在做什么,以及它的基数估计在哪里是错误的。如果您的查询执行良好,而成本似乎很高,那又如何?你很幸运,糟糕的成本并没有打乱计划。去吧。
1.如果您最终处理的是一个性能不佳的SQL,并且想知道瓶颈在哪里,那么唯一能确保准确性的方法就是使用等待采样数据。自11 g以来,每个Oracle数据库都有公开了
sql_plan_line_id
的ASH数据,这些数据可用于查找计划中的哪个步骤花费了您最多的查询时间,并将调优工作集中在该点。查找sql_id
并查询v$active_session_history
,然后按sql_plan_line_id分组,计算行数。行计数是在该步骤上花费的秒数。您可以从v$sql_plan_monitor
中获取每步的实际基数信息,这将有助于解释您在ASH中看到的计时,从而进一步帮助您进行调查。