Oracle SQL запрос - неожиданный план запроса - PullRequest
2 голосов
/ 10 марта 2010

У меня очень простой запрос, который дает неожиданные результаты. Советы по устранению неполадок приветствуются.

Упрощенно, запрос:

SELECT Obs.obsDate, 
       Obs.obsValue, 
       ObsHead.name
  FROM ml.Obs Obs 
  JOIN ml.ObsHead ObsHead ON ObsHead.hdId = Obs.hdId
 WHERE obs.hdId IN (53, 54)

Это дает мне стоимость запроса: 963 . Однако, если я изменю запрос на:

SELECT Obs.obsDate, 
       Obs.obsValue, 
       ObsHead.name
  FROM ml.Obs Obs 
  JOIN ml.ObsHead ObsHead ON ObsHead.hdId = Obs.hdId
 WHERE ObsHead.name IN ('BP SYSTOLIC', 'BP DIASTOLIC')

Несмотря на то, что он (должен) возвращать те же данные, ориентировочная стоимость возрастает до 17688 . Где проблема здесь, вероятно, кроется? Спасибо.

Редактировать: В плане запросов говорится, что индекс для ObsHead.Name используется для сканирования диапазона, а доступ к таблице в ObsHead стоит только 4. Существует еще один индекс для Obs.hdId, который используется для сканирования диапазона, стоящего 94: это объединение Nested Loops между таблицами, которое увеличивается до 17K.

Ответы [ 4 ]

1 голос
/ 13 марта 2010

Как уже говорилось, стоимость плана не предназначена для сравнения двух разных запросов, а только для сравнения разных путей для одного и того же запроса.

Это только предположение, но в этом случае поле кардинальности плана может быть более полезным для вас. Если индекс в OBSHEAD не является уникальным, и статистика была собрана с использованием оценки, то оптимизатор может не знать точно, сколько строк следует ожидать при запросе этой таблицы. Количество элементов подскажет вам, верно ли это или нет (в идеале вы должны увидеть количество элементов 2 для OBSHEAD).

Еще одно предложение - проверить статистику на OBS. Кажется вероятным, что эта таблица часто растет, и в этом случае 28 января недостаточно, чтобы собрать статистику. Предполагая, что для этой таблицы включен мониторинг, приведенные ниже запросы могут сообщить вам, устарела ли статистика и нужно ли ее обновить.

select owner, table_name, last_analyzed, stale_stats
from all_tab_statistics
where owner = 'ML' and table_name = 'OBS';

select owner, index_name, last_analyzed, stale_stats
from all_ind_statistics
where owner = 'ML' and table_name = 'OBS';
1 голос
/ 11 марта 2010

Затраты полезны только для сравнения разных планов для одного запроса; они не очень полезны для сравнения разных запросов.

Вам нужно посмотреть на планы и сравнить их с точки зрения действий, которые они выполняют.

Я подозреваю, что фактическая производительность этих запросов будет схожей, однако было бы интересно узнать, использует ли первый запрос хеш-соединение, что может помочь, если процент совпадений в obs, которые совпадают, значителен.

1 голос
/ 11 марта 2010

Мне кажется, что расходы, предоставляемые оптимизатором, интересны, но не особенно полезны. Лучший способ сравнить запросы - это запустить их и посмотреть, как они работают относительно друг друга.

Делись и наслаждайся.

1 голос
/ 10 марта 2010

Вероятно, существует индекс hdId (который существует, если это первичный ключ, что, как я подозреваю, имеет место), а не name, что означает, что второй запрос должен будет выполнить полное сканирование таблицы.

...