SQL является декларативным языком, а не процедурным языком. На самом деле выполняется, в основном, DAG-ориентированный ациклический граф - компонентов, которые вы, вероятно, не распознаете как конструкции SQL (такие как «hash join» или «filter» или «sort»).
Два запроса, о которых вы упомянули с условиями name
и age
, будут скомпилированы по существу в одну и ту же скомпилированную форму. Если у вас есть соответствующие индексы или разделы, оба запроса будут использовать их. Если вы этого не сделаете, то они могут выполнить логические условия в разных порядках. Однако большие затраты при таком запросе - это полное сканирование таблицы, а не отдельные сравнения.
В некоторых редких случаях вы можете быть уверены, что условия выполняются в определенном порядке, особенно если у вас дорогая пользовательская функция. Компилятор часто делает это за вас. Если нет, вы можете использовать выражение case
:
where (case when col <> 0 then 0
when expensive_function( . . . ) then 1
else 0
end) = 1
Это будет выполнять дорогостоящую функцию только тогда, когда col = 0
, потому что выражения case
оценивают свои выражения в последовательном порядке (в неагрегированном запросе).
Что касается кэширования, это зависит от сервера и параметров. Как правило, базы данных кэшируют планы запросов, поэтому их не нужно перекомпилировать. И это часто на уровне подготовленного оператора, а не текста запроса. Базы данных обычно не кэшируют результаты, потому что данные в базовых таблицах могут измениться.