Оптимизируются ли условные подзапросы, если условие ложно? - PullRequest
4 голосов
/ 20 мая 2010

У меня есть таблица foo и панель таблиц, где у каждого foo может быть строка (и строка может принадлежать нескольким foos).

Теперь мне нужно выбрать все столбцы. Мой sql выглядит так

SELECT * 
  FROM foo f 
 WHERE [...] 
   AND ($param IS NULL OR (SELECT ((COUNT(*))>0) 
                             FROM bar b 
                            WHERE f.bar = b.id))

с заменой $ param во время выполнения.

Вопрос в следующем: будет ли выполняться подзапрос, даже если param равен нулю, или dbms оптимизирует этот подзапрос?

Мы используем mysql, mssql и oracle. Есть ли разница между ними в отношении вышеизложенного?

Ответы [ 2 ]

2 голосов
/ 20 мая 2010

Это зависит. Если вы передаете этот запрос СУБД каждый раз, то компилятор должен понимать, что ему не нужно вызывать подзапрос. Если это статическая процедура, то это зависит от того, как компилятор хранит план выполнения. Если он сохраняет план выполнения при первом вызове процедуры и в первый раз, когда она вызывается, $ param не равен null, тогда он может фактически вызывать подзапрос при каждом запуске процедуры.

В другом примечании вы должны рассмотреть Exists вместо Count (*) для этого типа проверки

Select ..
From foo f
Where ....
    And ( $param Is Null
            Or Exists   (
                        Select 1
                        From bar b
                        Where b.id = f.bar
                        ))
1 голос
/ 20 мая 2010

В этом случае я рекомендую выполнять оптимизацию самостоятельно в коде приложения, а не полагаться на оптимизатор из 3 разных СУБД, чтобы последовательно обрабатывать это так, как вы хотите.

Если $ param равно нулю, просто выберите из таблицы foo. Если нет, присоединяйтесь к столу бара.

псевдо-код:

if ($param is null)
  SELECT * 
  FROM foo f 
  WHERE [...] 
else
  SELECT distinct f.* 
  FROM foo f 
  inner join bar b on f.bar = b.id
  WHERE [...] 
end if
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...