2

Я пишу аналитическое программное обеспечение, которое генерирует сложные запросы. При создании предложения where может случиться, что в одном поле базы данных добавляются несколько ограничений. Мне было интересно, перезаписывает ли PostgreSQL несколько ограничений в более простые. Я сделал несколько тестов:Оптимизация и условия в postgresql

SELECT COUNT(id) FROM employee WHERE age BETWEEN 18 AND 40; 

Я побежал это 10 раз, и среднее время, проведенное, составляло 65 мс. Теперь я сделать запрос немного дольше, но тривиальное для оптимизации:

SELECT COUNT(id) FROM employee WHERE 
(age BETWEEN 18 AND 40) AND 
(age BETWEEN 18 AND 40) AND 
(age BETWEEN 18 AND 40); 

Этот запрос занимает 100 мс в среднем, что намного медленнее. Кроме того, следующий запрос:

SELECT COUNT(id) FROM employee WHERE 
(age BETWEEN 28 AND 70) AND 
(age BETWEEN 25 AND 40) AND 
(age BETWEEN 22 AND 33) AND 
(age BETWEEN 18 AND 30); 

принимает 105ms в среднем, в то время как это эквивалентно:

SELECT COUNT(id) FROM employee WHERE age BETWEEN 28 AND 30; 

, который работает в два раза быстрее.

Эти запросы семантически эквивалентны, и я ожидал, что они будут оптимизированы в один и тот же запрос, прежде чем даже планировщик коснется их. Это похоже на низко висящие фрукты для перезаписывающего запроса. Есть ли скрытая конфигурация, которую я не вижу? Я использую postgresql 9.4.5.

Спасибо!

ответ

1

Оптимизатор не сгибает смежные диапазоны вместе. Он не выполняет такого рода анализ уровня данных.

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

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

TL; DR: Этот блок не будет автоматически оптимизирован планировщиком.

В будущем, однако: всегда предоставляет вашу версию PostgreSQL и вывод explain (buffers, analyze) для запроса/запросов.

Смежные вопросы