ВИКОРИСТАННЯ конструкції в пункті JOIN може ввести бар'єри оптимізації в певних випадках?


35

Мені було звернуто увагу, що USINGконструкція (замість ON) у FROMпункті SELECTзапитів може вводити бар’єри оптимізації в певних випадках.

Я маю на увазі це ключове слово:

ВИБІР *
ВІД a
ПРИЄДНАЙТЕСЬ b ВИКОРИСТАННЯ (a_id)

Просто у більш складних випадках.

Контекст: цей коментар до цього питання .

Я цим користуюся багато і досі нічого не помічав. Мені буде дуже цікаво тестовий випадок, що демонструє ефект або будь-які посилання на додаткову інформацію. Мої пошукові зусилля виявилися порожніми.

Ідеальною відповіддю був би тестовий випадок, який показуватиме б USING (a_id)низьку ефективність у порівнянні з альтернативним пунктом приєднання ON a.a_id = b.a_id- якщо це насправді може статися.


2
@kgrittn: Ось що я взагалі очікував поки що: USINGце трохи швидше - оскільки це призводить до одного стовпчика менше в матриці результатів. Ваші висновки відносяться до 2005 та 2008 років. Я припускаю, що будь-які проблеми вже були виправлені. Однак я можу побачити можливе обмеження: JOIN з, USINGможливо, доведеться застосовувати для того , щоб отримані з'єднувальні стовпці були спільним продуктом. Тим самим потенційно обмежуючи варіанти переупорядкування JOIN.
Ервін Брандстеттер

1
Я знайшов цей потік, який може мати щось спільне з тим, щоб відмовитись від його використання так часто, як у мене, тому що ПЕРЕГЛЯД з умовою ВИКОРИСТАННЯ при з'єднанні може спричинити проблеми на дампа / відновленні: archives.postgresql.org/pgsql- bugs / 2011-06 / msg00030.php У мене все ще виникає відчуття, що з'явилася ще одна нитка, пов’язана з проблемами продуктивності використання USING, де вирішення проблеми було ввімкнено, але я думаю, я відмовлюся від його пошуку. Мабуть, безпечно використовувати його поза переглядами, і просто не забудьте спробувати ON замість цього як діагностичний крок, якщо запит повільний.
kgrittn

1
Схоже, що "використання" зробить код трохи читабельним, але я думаю, що обом полям потрібна однакова назва. Я не думаю, що використання матиме кращу продуктивність, ніж "увімкнено", тому що БД потрібно все-таки проводити відповідність, це як вибірка має таку ж продуктивність, що і приєднання (виправте мене, якщо я помиляюся), Різниця полягає в тому, що Join є чистішим та легшим у обслуговуванні.
jcho360

2
@HLGEM: Це просто символічна назва, і лише з двома таблицями, як у моєму прикладі, немає місця для плутанини. І все-таки я змінив питання. Не хотілося б заохочувати нещасне використання idназви стовпців.
Ервін Брандстеттер

2
@ChristiaanWesterbeek: Я не згоден. "Місце для" для глибинної відповіді на Postgres - це (все-таки) розсилка. Лише небагато розробників Postgres активно працюють на SO, але всі розробники Postgres та експерти читають список розсилки
a_horse_with_no_name

Відповіді:


12

Ервін: Я б погоджувався з думкою, що використання USING, що спричиняє жорстке впорядкування, може створити багато кращих випадків, коли оптимальні плани будуть виключені. Нещодавно я допоміг комусь, у кого було щось подібне у його запиті:

LEFT JOIN ( 
     a 
     JOIN b ON a.id = b.a_id
     JOIN c ON b.c_id = c.id
) ON a.id = something.a_id
LEFT JOIN (
     table1 t1
     JOIN table2 t2 ON t1.some_field = t2.other_field
     JOIN talbe3 t3 ON t2.yafield = t3.something_else
) ON ....
repeat a few more times

У його випадку найгірше з цих блоків об'єднання викликало вкладення вкладеного циклу через 200k рядків, приблизно в 20 тис. Разів (зробіть математику), і оскільки ключі не вдалося натиснути на індекси, це було послідовною скануванням. Це означало, що загальний запит зайняв близько 3 годин через каскадні зміни плану. Розподіливши ліве з'єднання, клавіші можна було натиснути вниз і запит запустився за лічені секунди. Звичайно, це не зовсім рівнозначно, тому планувальник не може ставитись до них як до рівнозначних, і тому було залишено з'ясувати цей план як хеш-з'єднання, а потім робити вкладений цикл, який був болісно повільним.

Щоразу, коли ви жорстко змушуєте об'єднання проходити в певному порядку, ви вводите випадки, коли ключова інформація про фільтр ще не доступна при виконанні плану, і тому, що може бути зроблено пізніше при швидкому скануванні / хеш-приєднанні можливо, доведеться робити набагато повільніше під час вкладеного циклу / послідовного сканування, і, хоча вищезазначений фрагмент не є одразу еквівалентним, він показує ту саму проблему.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.