Oracle mechanics

20.01.2009

(Очередной) аргумент против +RULE в Oracle 11g

Filed under: Oracle — Игорь Усольцев @ 16:41
Tags: , ,

Ситуация — достаточно противоречивый запрос с хинтом RULE даёт ошибочный результат.

SELECT *
  FROM (SELECT /*+RULE*/
         T1.COL1, T1.COL2,
          FROM T1, T2, (SELECT COL1, COL2 FROM T3 WHERE COL3 = '***') V1
         WHERE T2.COL1 = T1.COL1(+)
           AND T1.COL2 IS NOT NULL
           AND V1.COL1 = T2.COL1
           AND V1.COL2 = T2.COL2
           AND T2.COL2 = '$$$'
         ORDER BY T1.COL1)
 WHERE ROWNUM <= 200

«Достаточно противоречивый» — поскольку в условиях есть явное логическое противоречие в части OUTER JOIN: условия T1.COL2 IS NOT NULL и T1.COL1(+) взаимно исключают друг друга.
Результат запроса становится правильным, если

  1. избавиться от хинта RULE
  2. либо удалить очевидно лишний OUTER JOIN (+)
  3. либо удалить условие WHERE ROWNUM <= 200
  4. либо пересоздать таблицу T1 в той же схеме

Специалисты Oracle support честно пытались помочь и указали причину (точнее, симптом) появления неправильного результата запроса — странный (но логически корректный) предикат в плане выполнения

6 -  filter(NVL2(ROWID,NVL("T1"."COL2",'N'),NULL) IS NOT NULL)

вместо ожидаемого

6 - filter("T1"."COL2" IS NOT NULL)

Т.е. неправильный результат является, видимо, следствием стечения обстоятельств, которое заставляет Rule Based Optimizer (RBO) выбрать ошибочный план выполнения.

В итоге, после рекомендованного обновления Oracle 11.1.0.6 -> 11.1.0.7 (никак не повлияло), и,  поскольку «эффект» так и не удалось воспроизвести ни в одной другой схеме, а завести баг по запросу с хинтом RULE (RBO) невозможно, для решения проблемы был выбран вариант №4 — пересоздание таблицы.

Добавить комментарий »

Комментариев нет.

RSS feed for comments on this post. TrackBack URI

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s

Блог на WordPress.com.

%d такие блоггеры, как: