如何从Oracle Explain Plan中查找瓶颈

wmvff8tz  于 2023-08-04  发布在  Oracle
关注(0)|答案(1)|浏览(101)

任何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 |

字符串

yhuiod9q

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中看到的计时,从而进一步帮助您进行调查。

相关问题