Прощу прощения. Заменил в запросе имена таблиц и альясов на другие, а планы не переименовал.
Изменил пример на через SELECT - для наглядности.
Таблица BATCH - около 5500 записей.
Таблица CHARGE - около 120 000.
Таблица PERIOD_ACCOUNT - около 1 000 000 записей.
Код: Выделить всё
SELECT
(SELECT
SUM(C.AMOUNT_FULL)
FROM
BATCH AS B
INNER JOIN CHARGE AS C ON B.ID = C.ID_BATCH
WHERE
(C.ID_ABONENT = :ID_ABONENT) AND (B.ID_PERIOD = PA.ID_PERIOD))
FROM
PERIOD_ACCOUNT PA
WHERE
PA.ID_PERIOD = :ID_PERIOD
Получаем план
PLAN JOIN (B INDEX (FK_BATCH_PERIOD), C INDEX (FK_CHARGE_BATCH, FK_CHARGE_ABONENT))
PLAN (PA INDEX (FK_PERIOD_ACCOUNT_PERIOD))
FK_BATCH_PERIOD - индекс по BATCH.ID_PERIOD. Селективность - 0,022222.
FK_CHARGE_BATCH - индекс по CHARGE.ID_BATCH. Селективность - 0,000184.
FK_CHARGE_ABONENT - индекс по CHARGE.ID_ABONENT. Селективность 0,000079.
Запрос:
Код: Выделить всё
SELECT
(SELECT
SUM(C.AMOUNT_FULL)
FROM
BATCH AS B
INNER JOIN CHARGE AS C ON B.ID = C.ID_BATCH
WHERE
(C.ID_ABONENT = :ID_ABONENT) AND (B.ID_PERIOD = :ID_PERIOD))
FROM
PERIOD_ACCOUNT PA
WHERE
PA.ID_PERIOD = :ID_PERIOD
План:
PLAN JOIN (C INDEX (FK_CHARGE_ABONENT), B INDEX (PK_BATCH))
PLAN (PA INDEX (FK_PERIOD_ACCOUNT_PERIOD))
То есть, при использовании в подзапросе условия по параметру, применяется более селективный индекс по коду абонента (что правильно), а при использовании условия по полю мастер-таблицы - сначала индекс по коррелируемому поля, а затем джойн и отбор по абоненту.