PostgreSQL Выбор некоторых атрибутов, которые равны =, другие меньше, чем <в вложенном SQL-запросе выбора - PullRequest
0 голосов
/ 05 сентября 2018

Я написал запрос SQL, который выполнялся в течение 30 минут, и я думаю, что он был сформулирован неправильно.

Упрощенная схема базы данных имеет атрибуты CompanyName, Customer, ExpiryDate и DeliveryDate.

Приведенный ниже запрос хорошо работает при выборе всех кортежей, которые были проданы определенному клиенту «Компания XYZ»:

(SELECT a.* FROM certificates a
WHERE (a."CompanyName", a."ExpiryDate") 
IN 
(SELECT b."CompanyName", b."ExpiryDate" 
FROM certificates b 
WHERE b."Customer" = 'Company XYZ') )

Я хочу выбрать подмножество результатов запроса выше, где DeliveryDate отношения a (outer SELECT) строго после DeliveryDate отношения b (inner SELECT).

Это может не иметь никакого логического смысла, но я должен найти все кортежи, которые изменили DeliveryDate в данных, так что это очень важно.

Это мой запрос, который не будет выполнен:

(SELECT a.* FROM certificates a
WHERE (a."CompanyName", a."ExpiryDate")
IN 
(SELECT b."CompanyName", b."ExpiryDate" 
FROM certificates b WHERE b."Customer" = 'Company XYZ' 
AND b."DeliveryDate" < a."DeliveryDate") )

1 Ответ

0 голосов
/ 05 сентября 2018

Первый запрос является простым и имеет «независимый подзапрос». Следовательно, этот подзапрос может быть полностью предварительно обработан (и выполняется только один раз) перед выполнением основного запроса. Это быстро.

Во втором случае у вас есть «коррелированный подзапрос». Коррелированный подзапрос должен быть запущен один раз для каждой потенциальной строки в основном запросе. Вот почему это медленно. Чем больше строк в основной таблице, тем медленнее становится запрос.

Коррелированные подзапросы присуще медленнее, чем некоррелированные. Что вы можете с этим поделать? Попробуйте использовать индексы. Простой индекс поможет, а индекс покрытия сделает это намного быстрее.

  • Простой индекс (несколько быстрее):

    create index ix1 on certificates ("Customer");
    

    «Простой индекс» включает столбцы, которые соответствуют основной таблице.

  • Индекс покрытия (намного быстрее):

    create index ix2 on certificates ("Customer", "DeliveryDate");
    

    «Индекс покрытия» включает все столбцы, используемые запросом, в корреляции, фильтрации и извлечении данных.

Ну, в конце вам нужно будет попробовать их, чтобы увидеть, насколько они улучшают ваш запрос. Но помните, что коррелированные подзапросы по определению медленны.

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