Кроме того, Oracle может по-разному оптимизировать запросы в зависимости от того, включает ли запрос буквальные или связанные значения.
SELECT SOMETHING
FROM MYTABLE
WHERE NAME = 'SOME-NAME'
AND TIME BETWEEN 7 AND 41;
Держу пари, что Oracle знает кое-что о распределении данных в столбце TIME
и делает предположение - возможно, используя устаревшую статистику - относительно того, какой процент строк и блоков (то есть селективность) этого столбца , Проверьте, есть ли в этом столбце гистограмма.
Однако такой запрос:
SELECT SOMETHING
FROM MYTABLE
WHERE NAME = 'SOME-NAME'
AND TIME BETWEEN MY_FUNC('7') AND MY_FUNC('41');
, вероятно, будет оптимизирован как семантически эквивалентный:
SELECT SOMETHING
FROM MYTABLE
WHERE NAME = 'SOME-NAME'
AND TIME BETWEEN :some_bind AND :some_other_bind;
Поскольку Oracle не знает, что делает MY_FUNC('7')
- или даже MY_FUNC('7')
всегда будет возвращать одно и то же значение 7 - если вы не сообщили Oracle о детерминированности функции. Таким образом, мой опыт показывает, что Oracle в большинстве случаев принимает удар в темноте и предпочитает индекс с высоким коэффициентом кластеризации. Кажется, кажется, что даже если индекс не лучший выбор, по крайней мере, он сводит к минимуму риск падения, посещая как можно меньше блоков данных.
Я рекомендую выяснить для себя, почему он ведет себя по-разному - выполните трассировку 10053 каждого запроса:
alter session set events = '10053 trace name context forever;
run sql
alter session set events = '10053 trace name context off;