Этот конкретный запрос работал нормально, пока мы не были в 11i, но как только мы переключились на 12c, запрос действительно плохо. Я попытался удалить подсказку, и, похоже, это немного лучше, но наш администратор базы данных хочет, чтобы мы удалили все несколько подзапросов, которые вызывают сериализацию различных подэтапов. Я не понимаю, как это изменить. Любые указатели на то, с чем я могу начать или начать?Нужна помощь в оптимизации запроса Oracle в 12c
WITH
-- Get all active accounts that have not been suspended and the suspension rules
-- apply for the account
TT1 AS (SELECT
pl.employer_id,
ma.employee_id,
ma.member_account_id,
pl.plan_id
FROM sa_plans pl,
sa_accounts ma
WHERE TRUNC(SYSDATE) BETWEEN pl.start_date AND NVL(pl.end_date, TRUNC(SYSDATE))
AND pl.employer_id = 23
AND pl.plan_type_id NOT IN (4
,1)
AND pl.plan_id = ma.plan_id
AND sa_mc_info.fn_ee_susp_exempt(ma.employee_id, DECODE(pl.plan_type_id, 1, 6 ,5)) = 0
AND p_outstanding_threshold_perc > 0
AND NVL(ma.auto_suspension_flag, 0) = 0
AND TRUNC(SYSDATE) BETWEEN ma.account_effective_date AND NVL(ma.account_end_date, TRUNC(SYSDATE))
AND ma.account_effective_date != NVL(ma.account_end_date, ma.account_effective_date + 1)
),
-- Get all accounts that were active during the plan year for the current accounts
-- and the outstanding transactions
TT2 AS (SELECT /*+ MATERIALIZE */
ma1.member_account_id,
ma1.plan_id,
ma1.employee_id ,
wwsa.sa_mc_info.fn_acnt_unverified_txns(ma1.member_account_id) outstd_amount
FROM sa_accounts ma1,
TT1 ma
WHERE ma1.account_effective_date != NVL(ma1.account_end_date, ma1.account_effective_date + 1)
AND ma1.plan_id = ma.plan_id
AND ma1.employee_id = ma.employee_id
AND ma1.member_account_id = TT1.member_account_id),
-- Sum the outstanding transactions for the EE and plan
TT3 AS (SELECT /*+ MATERIALIZE ORDERED */
TT1.member_account_id,
SUM(TT2.outstd_amount) outstd_amount
FROM TT1,
TT2
WHERE TT1.employee_id = TT2.employee_id
AND TT1.plan_id = TT2.plan_id
GROUP BY TT1.member_account_id
HAVING SUM(TT2.outstd_amount) > 0),
-- Get the current account balance for accounts with outstanding transactions
TT4 AS (SELECT /*+ MATERIALIZE ORDERED */
TT1.*,
sa_bal_info.fn_account_balance(TT1.member_account_id) balance,
TT3.outstd_amount
FROM TT1,
TT3
WHERE TT1.member_account_id = TT3.member_account_id),
-- Get the list of accounts that need to be suspended
TT5 as (SELECT /*+ MATERIALIZE */
member_account_id,
employee_id
FROM TT4
WHERE outstd_amount > balance * p_outstanding_threshold_perc
AND outstd_amount > NVL(p_minimum_threshold_amount, 0) )
SELECT *
FROM TT5
ORDER BY employee_id;
Это объяснить план
-----------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 26 | 8622 (1)| 00:00:01 |
| 1 | TEMP TABLE TRANSFORMATION | | | | | |
| 2 | LOAD AS SELECT | SYS_TEMP_0FD9D666F_DCBC1560 | | | | |
| 3 | NESTED LOOPS | | 4 | 252 | 8600 (1)| 00:00:01 |
| 4 | NESTED LOOPS | | 1707 | 252 | 8600 (1)| 00:00:01 |
|* 5 | TABLE ACCESS BY INDEX ROWID BATCHED| SA_PLANS | 3 | 84 | 8452 (1)| 00:00:01 |
| 6 | INDEX FULL SCAN | SA_PLANS_PK | 19218 | | 75 (2)| 00:00:01 |
|* 7 | INDEX RANGE SCAN | SA_ACCOUNTS_N03 | 569 | | 2 (0)| 00:00:01 |
|* 8 | TABLE ACCESS BY INDEX ROWID | SA_ACCOUNTS | 1 | 35 | 67 (0)| 00:00:01 |
| 9 | LOAD AS SELECT | SYS_TEMP_0FD9D6670_DCBC1560 | | | | |
| 10 | NESTED LOOPS | | 3 | 177 | 8 (0)| 00:00:01 |
| 11 | NESTED LOOPS | | 3 | 177 | 8 (0)| 00:00:01 |
| 12 | VIEW | | 1 | 26 | 2 (0)| 00:00:01 |
| 13 | TABLE ACCESS FULL | SYS_TEMP_0FD9D666F_DCBC1560 | 1 | 22 | 2 (0)| 00:00:01 |
|* 14 | INDEX RANGE SCAN | SA_ACCOUNTS_N01 | 3 | | 2 (0)| 00:00:01 |
|* 15 | TABLE ACCESS BY INDEX ROWID | SA_ACCOUNTS | 3 | 99 | 6 (0)| 00:00:01 |
| 16 | LOAD AS SELECT | SYS_TEMP_0FD9D6671_DCBC1560 | | | | |
|* 17 | FILTER | | | | | |
| 18 | HASH GROUP BY | | 1 | 41 | 5 (20)| 00:00:01 |
|* 19 | HASH JOIN | | 1 | 41 | 4 (0)| 00:00:01 |
| 20 | VIEW | | 1 | 17 | 2 (0)| 00:00:01 |
| 21 | TABLE ACCESS FULL | SYS_TEMP_0FD9D666F_DCBC1560 | 1 | 22 | 2 (0)| 00:00:01 |
| 22 | VIEW | | 1 | 24 | 2 (0)| 00:00:01 |
| 23 | TABLE ACCESS FULL | SYS_TEMP_0FD9D6670_DCBC1560 | 1 | 30 | 2 (0)| 00:00:01 |
| 24 | LOAD AS SELECT | SYS_TEMP_0FD9D6672_DCBC1560 | | | | |
|* 25 | HASH JOIN | | 1 | 78 | 4 (0)| 00:00:01 |
| 26 | VIEW | | 1 | 52 | 2 (0)| 00:00:01 |
| 27 | TABLE ACCESS FULL | SYS_TEMP_0FD9D666F_DCBC1560 | 1 | 22 | 2 (0)| 00:00:01 |
| 28 | VIEW | | 1 | 26 | 2 (0)| 00:00:01 |
| 29 | TABLE ACCESS FULL | SYS_TEMP_0FD9D6671_DCBC1560 | 1 | 19 | 2 (0)| 00:00:01 |
| 30 | LOAD AS SELECT | SYS_TEMP_0FD9D6673_DCBC1560 | | | | |
|* 31 | VIEW | | 1 | 52 | 2 (0)| 00:00:01 |
| 32 | TABLE ACCESS FULL | SYS_TEMP_0FD9D6672_DCBC1560 | 1 | 48 | 2 (0)| 00:00:01 |
| 33 | SORT ORDER BY | | 1 | 26 | 3 (34)| 00:00:01 |
| 34 | VIEW | | 1 | 26 | 2 (0)| 00:00:01 |
| 35 | TABLE ACCESS FULL | SYS_TEMP_0FD9D6673_DCBC1560 | 1 | 12 | 2 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------------------------
Каков был план предыдущей версии (11i - это версия Oracle Applications, я предполагаю, что ваше намерение здесь состояло в том, чтобы сказать, что она хорошо работала в предыдущей версии базы данных Oracle, такой как 11g)? В запросе, который вы опубликовали, есть куча намеков, но в тексте вашего вопроса говорится, что вы удалили «намек», который сбивает с толку. Вывешен ли план запроса из версии запроса со всеми подсказками? Или тот, у кого есть намеки? –
Отсутствует «предикатная информация» - она печатается под таблицей плана, вы можете дополнить ее планом? – krokodilko
Я бы вытащил подсказки MATERIALIZE и ORDERED (Oracle решит, что ему следует использовать), и вместо этого я попробую установить параболический (8) подсказку. Оптимизируя его «цель-стрельба-цель-стрелять ...», вы должны попробовать несколько способов, потому что его в зависимости от количества вещей – Thomas