Как я могу прочитать и проанализировать план объяснения Oracle? - PullRequest
0 голосов
/ 19 марта 2019

Я сгенерировал план объяснения для одного из моих запросов.Полный объяснительный план приведен ниже

| Id  | Operation                                | Name                       | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                         |                            |     1 |   202 |   441   (2)| 00:00:06 |
|   1 |  NESTED LOOPS OUTER                      |                            |     1 |   202 |   441   (2)| 00:00:06 |
|   2 |   NESTED LOOPS OUTER                     |                            |     1 |   192 |   441   (2)| 00:00:06 |
|   3 |    NESTED LOOPS OUTER                    |                            |     1 |   188 |   441   (2)| 00:00:06 |
|   4 |     NESTED LOOPS OUTER                   |                            |     1 |   185 |   441   (2)| 00:00:06 |
|   5 |      NESTED LOOPS OUTER                  |                            |     1 |   168 |   439   (2)| 00:00:06 |
|   6 |       NESTED LOOPS OUTER                 |                            |     1 |   159 |   438   (2)| 00:00:06 |
|*  7 |        FILTER                            |                            |       |       |            |          |
|   8 |         NESTED LOOPS OUTER               |                            |     1 |   153 |   437   (2)| 00:00:06 |
|   9 |          NESTED LOOPS OUTER              |                            |    47 |  6392 |   343   (3)| 00:00:05 |
|  10 |           NESTED LOOPS                   |                            |    46 |  6026 |   297   (3)| 00:00:04 |
|* 11 |            HASH JOIN OUTER               |                            |    46 |  5888 |   297   (3)| 00:00:04 |
|* 12 |             HASH JOIN                    |                            |    41 |  4961 |   294   (3)| 00:00:04 |
|* 13 |              HASH JOIN                   |                            |    41 |  4674 |   292   (3)| 00:00:04 |
|* 14 |               HASH JOIN OUTER            |                            |     3 |    24 |     3  (34)| 00:00:01 |
|  15 |                INDEX FULL SCAN           | COM_DOCUMENT_TYPES_PK      |     3 |     9 |     1   (0)| 00:00:01 |
|* 16 |                INDEX FULL SCAN           | COM_DOCUMENT_TYPES_MLD_PK  |     3 |    15 |     1   (0)| 00:00:01 |
|* 17 |               TABLE ACCESS BY INDEX ROWID| COM_DOCUMENTS              |    41 |  4346 |   289   (3)| 00:00:04 |
|* 18 |                INDEX RANGE SCAN          | COM_DOCUMENTS_IDX2         |  8064 |       |    17   (6)| 00:00:01 |
|  19 |              TABLE ACCESS BY INDEX ROWID | WF_PROCESS_STATUS          |     5 |    35 |     2   (0)| 00:00:01 |
|* 20 |               INDEX RANGE SCAN           | WF_PROCESS_STATUS_IDX1     |     5 |       |     1   (0)| 00:00:01 |
|* 21 |             TABLE ACCESS FULL            | WF_PROCESS_STATUS_MLD      |    24 |   168 |     2   (0)| 00:00:01 |
|* 22 |            INDEX UNIQUE SCAN             | SYS_C0021772               |     1 |     3 |     0   (0)| 00:00:01 |
|* 23 |           INDEX RANGE SCAN               | COM_MUNICIPAL_LICENSE_IDX2 |     1 |     5 |     1   (0)| 00:00:01 |
|  24 |          TABLE ACCESS BY INDEX ROWID     | LCT_SPONSOR                |     1 |    17 |     2   (0)| 00:00:01 |
|* 25 |           INDEX UNIQUE SCAN              | LCT_SPONSOR_PK             |     1 |       |     1   (0)| 00:00:01 |
|* 26 |        INDEX UNIQUE SCAN                 | AUTH_USERS_PK              |     1 |     6 |     1   (0)| 00:00:01 |
|* 27 |       INDEX UNIQUE SCAN                  | AUTH_USERS_MLD_UK1         |     1 |     9 |     1   (0)| 00:00:01 |
|  28 |      TABLE ACCESS BY INDEX ROWID         | LCT_SPONSOR_BRANCHES       |     1 |    17 |     2   (0)| 00:00:01 |
|* 29 |       INDEX UNIQUE SCAN                  | BRANCHES_ID1               |     1 |       |     1   (0)| 00:00:01 |
|* 30 |     INDEX UNIQUE SCAN                    | LCM_REGION_PK              |     1 |     3 |     0   (0)| 00:00:01 |
|* 31 |    INDEX UNIQUE SCAN                     | LCM_WILAYAT_PK             |     1 |     4 |     0   (0)| 00:00:01 |
|* 32 |   INDEX UNIQUE SCAN                      | LCM_VILLAGE_PK             |     1 |    10 |     0   (0)| 00:00:01 |

Полный запрос приведен ниже для справки:

SET SERVEROUTPUT ON;
DECLARE
    CR VARCHAR2(32767) := '1048830';
    DUID VARCHAR2(32767) := '1048830-10804-7174-72';
    ST NUMBER := 105;
    DTID NUMBER := 2;
    RESP VARCHAR2(32767);
BEGIN
    SELECT D.*
    FROM COM_DOCUMENTS D
    INNER JOIN SYS_LABOUR_OFFICE LO ON D.LABOUR_OFFICE_ID=LO.ID
    LEFT JOIN COM_MUNICIPAL_LICENSE ML ON D.ID = ML.DOCUMENT_ID
    LEFT JOIN LCT_SPONSOR SP ON D.SPONSOR_NO = SP.SPONSOR_NO
    LEFT JOIN LCT_SPONSOR_BRANCHES LSB ON D.BRANCH_NO =LSB.ID
    INNER JOIN WF_PROCESS_STATUS PS ON D.CURRENT_STATUS_ID = PS.WF_PROCESS_STATUS_ID AND PS.WF_PROCESS_ID = 6
    LEFT JOIN WF_PROCESS_STATUS_MLD PSMLD ON PS.WF_PROCESS_STATUS_ID = PSMLD.WF_PROCESS_STATUS_ID AND PSMLD.LANGUAGE_ID = 1 
    LEFT JOIN AUTH_USERS AU1 ON D.CURRENT_FOLLOWER = AU1.USER_ID
    LEFT JOIN AUTH_USERS_MLD AU_MLD1 ON AU1.USER_ID = AU_MLD1.USER_ID AND AU_MLD1.LANGUAGE_ID = 1
    INNER JOIN COM_DOCUMENT_TYPES DT ON D.DOC_TYPE_ID = DT.DOCUMENT_TYPE_ID
    LEFT JOIN COM_DOCUMENT_TYPES_MLD DTM ON DT.DOCUMENT_TYPE_ID = DTM.DOCUMENT_TYPE_ID AND DTM.LANGUAGE_ID=1
    LEFT JOIN LCM_REGION LR ON LSB.REGION_CODE = LR.REGION_CODE
    LEFT JOIN LCM_WILAYAT LW ON LSB.REGION_CODE = LW.REGION_CODE AND LSB.WILAYAT_CODE = LW.WILAYAT_CODE
    LEFT JOIN LCM_VILLAGE LV ON LSB.REGION_CODE = LV.REGION_CODE AND LSB.WILAYAT_CODE = LV.WILAYAT_CODE AND LSB.VILLAGE_CODE = LV.VILLAGE_CODE
    WHERE (CR = '' OR SP.CR_NO =  CR)
    AND (DUID = '' OR D.DOC_UNIQUE_IDENTIFIER = NVL(DUID,  D.DOC_UNIQUE_IDENTIFIER))
    AND (ST = -99 OR D.CURRENT_STATUS_ID =  ST)
    AND (DTID = -99 OR D.DOC_TYPE_ID =  DTID);

    DBMS_OUTPUT.PUT_LINE(RESP);
END;

Я очень новичок в Oracle и мне нужно понять, как я могуПрочитайте этот план объяснения.

Мне действительно нужно знать, как я могу оптимизировать запрос, объединить заказы и т. д., прочитав план объяснения.Надеюсь, что это поможет многим людям.

1 Ответ

0 голосов
/ 20 марта 2019

Я бы начал так.Таблицы разбиты на разделы и какие столбцы индексируются?Есть ли в таблицах последняя статистика?Есть ли у оракула все, что нужно для правильного выбора?Я удаляю / усекаю раздел и вставляю / вставляю с добавлением в эти таблицы, потому что HWM становится проблемой, если я удаляю с вставкой с добавлением.

То, что вы хотите, - это иметь Oracle, сделать правильный выбор плана выполнения.Вам нужны таблицы, разделы и индексы, чтобы иметь последнюю статистику по ним.

begin
    DBMS_STATS.GATHER_TABLE_STATS
    (OWNNAME            => lv_schema_from, 
     TABNAME            => lv_table_from, 
     ESTIMATE_PERCENT   => 15,     --15% for ~100000 of record, 15%-100% for less         METHOD_OPT         => 'FOR ALL COLUMNS SIZE AUTO', 
     GRANULARITY        => 'AUTO', --only if you have partitioned table
     DEGREE             => 8,      --parallel 
     CASCADE            => TRUE);  --cascade to indexes
end;

Это может изменить план выполнения (в лучшую сторону).

Впоследствии, если это тот же план выполненияЯ бы начал с типа соединения между таблицами и параллельной подсказкой (сколько ядер доступно?).

Что лучше?Чтение из D или LO сначала -> ведущая подсказка для самой маленькой таблицы таблиц с внутренним соединением между ними (на всякий случай).

Хочу ли я использовать индекс?если я посмотрю 9.000.000 записей в таблицу 300.000.000 (3%), используя индекс, это может занять полчаса.В моем случае быстрее использовать use_hash или полные подсказки, чем позволить индексу оракула идти.

Эксперимент ... разное количество ядер, PGA, SGA, статистика (наиболее важная) заставляет CBO по-разному оценивать оптимальный план выполнения длятот же запрос.

Лучше всего было бы обратиться к источнику проблемы, и это было бы ответом на вопрос, почему Oracle выбрала этот план выполнения? Большую часть времени статистика таблиц, разделов и индексов.

...