MySQL / PostgreSQL кеширует разбор / компиляцию запросов? - PullRequest
0 голосов
/ 12 мая 2018

Предположим, я выполняю запрос в MySQL (или PostgreSQL), скажем:

SELECT * FROM USER WHERE age = 20;

Анализирует ли ядро ​​базы данных и компилирует ли запрос / оператор каждый раз, когда я его выполняю?Или он содержит некоторый кэш предыдущих операторов / запросов?

Если он имеет механизм кэширования, обрабатывает ли он следующие два запроса по-разному?

/* first query */
SELECT * FROM USER WHERE age = 20 AND name = 'foo';

/* second query */
SELECT * FROM USER WHERE name = 'foo' AND age = 20;

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

Спасибо

1 Ответ

0 голосов
/ 12 мая 2018

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 оценивают свои выражения в последовательном порядке (в неагрегированном запросе).

Что касается кэширования, это зависит от сервера и параметров. Как правило, базы данных кэшируют планы запросов, поэтому их не нужно перекомпилировать. И это часто на уровне подготовленного оператора, а не текста запроса. Базы данных обычно не кэшируют результаты, потому что данные в базовых таблицах могут измениться.

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