Позвольте мне воссоздать:
CREATE TABLE RNS_RECON_HO (PROD_CODE NUMBER,
REFR_NUMB NUMBER,
NARR_1 VARCHAR2 (25),
SEQN_NUMB NUMBER primary key );
CREATE INDEX TESTTT ON RNS_RECON_HO (PROD_CODE);
CREATE INDEX TESTTT1 ON RNS_RECON_HO (REFR_NUMB);
CREATE INDEX TESTTT2 ON RNS_RECON_HO (NARR_1);
Теперь воспроизводя свой план:
SET AUTOTRACE ON
UPDATE
RNS_RECON_HO C
SET
C.REFR_NUMB =
(SELECT
SEQN_NUMB
FROM
RNS_RECON_HO P
WHERE
P.NARR_1 = C.NARR_1
AND P.SEQN_NUMB = P.REFR_NUMB
AND P.PROD_CODE = PROD_CODE)
WHERE
C.PROD_CODE = 0
AND C.REFR_NUMB = 0
AND C.NARR_1 = '3/13/201211013198693442091';
0 rows updated.
Execution Plan
----------------------------------------------------------
0 UPDATE STATEMENT Optimizer Mode=ALL_ROWS (Cost=2 Card=1 Bytes=78)
1 0 UPDATE RNS_RECON_HO
2 1 TABLE ACCESS FULL RNS_RECON_HO (Cost=2 Card=1 Bytes=78)
3 1 TABLE ACCESS BY INDEX ROWID RNS_RECON_HO (Cost=5 Card=1 Bytes=91)
4 3 INDEX RANGE SCAN TESTTT (Cost=1 Card=1)
Statistics
----------------------------------------------------------
190 recursive calls
0 spare statistic 3
0 gcs messages sent
25 db block gets from cache
0 physical reads direct (lob)
0 queue position update
0 queue single row
0 queue ocp pages
0 HSC OLTP Compressed Blocks
0 HSC IDL Compressed Blocks
0 rows processed
Причина:
Оптимизатор выбрать только использовать индекс, если он дешевле (меньше читает), чем сканирование таблицы. Обычно это означает, что критерии WHERE должны сопоставляться с ведущими (то есть самыми левыми) столбцами индекса. Таким образом, добавление индекса (PROD_CODE, REFR_NUMB, NARR_1) в столбцы клаузулов where будет избегать этого.
Для подтверждения проверить это один
CREATE INDEX TESTTT3 ON RNS_RECON_HO (PROD_CODE, REFR_NUMB, NARR_1);
SET AUTOTRACE ON
UPDATE
RNS_RECON_HO C
SET
C.REFR_NUMB =
(SELECT
SEQN_NUMB
FROM
RNS_RECON_HO P
WHERE
P.NARR_1 = C.NARR_1
AND P.SEQN_NUMB = P.REFR_NUMB
AND P.PROD_CODE = PROD_CODE)
WHERE
C.PROD_CODE = 0
AND C.REFR_NUMB = 0
AND C.NARR_1 = '3/13/201211013198693442091';
0 rows updated.
Execution Plan
----------------------------------------------------------
0 UPDATE STATEMENT Optimizer Mode=ALL_ROWS (Cost=1 Card=1 Bytes=78)
1 0 UPDATE RNS_RECON_HO
2 1 INDEX RANGE SCAN TESTTT3 (Cost=1 Card=1 Bytes=78)
3 1 TABLE ACCESS BY INDEX ROWID RNS_RECON_HO (Cost=27 Card=1 Bytes=91)
4 3 INDEX FULL SCAN TESTTT3 (Cost=26 Card=1)
Statistics
----------------------------------------------------------
1 recursive calls
0 spare statistic 3
0 gcs messages sent
0 db block gets from cache
0 physical reads direct (lob)
0 queue position update
0 queue single row
0 queue ocp pages
0 HSC OLTP Compressed Blocks
0 HSC IDL Compressed Blocks
0 rows processed
Но это просто изменить план, но никогда не обещает никаких улучшений производительности, с ограниченными входами вы дали.
ПОСЛЕДУЮЩИЕ:
Внешний запрос происходит FTS, поскольку она игнорирует индекс. Поэтому, когда мы помещаем составной ключ, индекс является прямым для оптимизатора и тот же самый используется. Sub-запрос использует индекс, поскольку он соединен с внешним запросом в индексированном столбце.
Как определить точный план не может быть достигнут на 100%, хотя вы можете быть рядом с возможным планом выполнения, следуя основным правилам.
Каков ваш основной ключ? Какой у вас индекс? У вас есть разделы? – SriniV
@realspirituals 'seqn_numb' - это PK, все запрошенные поля индексируются и да, таблица разделена. – bjan
Не могли бы вы разместить свою таблицу создания, индексные скрипты? ИЛИ установить его в sqlfiddle.com – SriniV