Два SQL имеют небольшую разницу, однако эффективность запросов сильно отличается, почему? - PullRequest
0 голосов
/ 22 мая 2019

Запрос sql1 ожидал, запрос sql2 довольно быстрый. И почему?В таблице c содержится около 40 000 записей, и поле col1 в основном пустое.

Первое условие sql1 и третье условие или второе условие и запрос третьего условия очень быстрые, но когда три условияЗапрашиваемая вместе, она становится медленнее и ждет.Это ошибка?

sql1:

SELECT a.id, b.id FROM a a
                        JOIN b b ON b_id=id
                        JOIN c c ON c_id=id
                        JOIN d d ON d_id=id
WHERE c.col1='col1'
  AND c.col_date <= TO_DATE('2019-05-14 00:00:00', 'yyyy-mm-dd hh24:mi:ss')
  AND c.col_date >= TO_DATE('2019-01-14 00:00:00', 'yyyy-mm-dd hh24:mi:ss')


sql2

SELECT a.id, b.id FROM a a
                        JOIN b b ON b_id=id
                        JOIN c c ON c_id=id
                        JOIN d d ON d_id=id
WHERE nvl(c.col1, '')='col1'
  AND c.col_date <= TO_DATE('2019-05-14 00:00:00', 'yyyy-mm-dd hh24:mi:ss')
  AND c.col_date >= TO_DATE('2019-01-14 00:00:00', 'yyyy-mm-dd hh24:mi:ss')

Ответы [ 2 ]

1 голос
/ 22 мая 2019

Это, вероятно, не "ошибка" в обычном смысле этого слова.Это просто случай, когда оптимизатор не выбирает правильный путь.

Учтите, что c действительно большой, а a действительно маленький, и у вас есть индекс, где первый столбец равен * 1005.*.

Первый запрос пытается использовать этот индекс.Но скажем, таблица c действительно большая и col1 распространяется по всем страницам данных.Итак, все данные должны быть прочитаны, но вы делаете это через индекс, который замедляет процесс.Если таблица больше доступной памяти, вы можете получить сбои.

Второй запрос не может использовать этот индекс.Таким образом, он находит другой путь выполнения.Он решает, что чтение a - лучший путь.a мало, а другие таблицы вносят небольшой вклад.Он может перейти непосредственно к соответствующим строкам в c - и затем применить условия фильтрации.

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

Вышеприведенное предназначено только для предоставления одного сценария, пытающегося объяснить, почему происходит нечто подобное.Оптимизатор в целом работает хорошо, но всегда есть возможности для улучшения.

1 голос
/ 22 мая 2019

Возможно, у вас есть functional index на nvl(c.col1, ''), а у столбца col1 нет индекса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...