Загальні вирази таблиць PostgreSQL та тимчасова таблиця?


11

Документація PostgreSQL на ЗО показує наступний приклад:

WITH regional_sales AS (
        SELECT region, SUM(amount) AS total_sales
        FROM orders
        GROUP BY region
     ), top_regions AS (
        SELECT region
        FROM regional_sales
        WHERE total_sales > (SELECT SUM(total_sales)/10 FROM regional_sales)
     )
SELECT region,
       product,
       SUM(quantity) AS product_units,
       SUM(amount) AS product_sales
FROM orders
WHERE region IN (SELECT region FROM top_regions)
GROUP BY region, product;

Він також зазначає:

Корисна властивість запитів WITH полягає в тому, що вони оцінюються лише один раз за виконання батьківського запиту, навіть якщо на них більше одного разу звертається батьківський запит або однорідний запит.

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


коли ви використовуєте CTE для створення запиту, додавання ще одного стовпця SELECTв WITHпросто вводить ім’я та повторний запуск. Хоча з тимчасовим столом знадобиться DROPі CREATE. З іншого боку, якщо ви будуєте запит і збираєтеся багато разів використовувати статичні дані - створення тимчасової таблиці з індексами безумовно вигідно проти CTE.
Вао Цун

@VaoTsun, якщо використовувати TEMPORARY TABLEз ON COMMIT DROPзапитом, це також лише питання зміни запиту та повторного запуску, правда? postgresql.org/docs/9.6/static/sql-createtable.html
Натан Лонг

Відповіді:


16

Є кілька тонких відмінностей, але нічого різкого:

  • Ви можете додати індекси до темп-таблиці;
  • Тимчасові таблиці існують протягом життя сеансу (або, якщо ON COMMIT DROP, транзакції), коли WITHзавжди чітко визначено запит;
  • Якщо запит викликає функцію / процедуру, він може бачити таблицю темпів, але він не може бачити жодних WITHтабличних виразів;
  • Тимчасова таблиця генерує VACUUMроботу над системними каталогами, WITHяка не потрібна. Для її створення / заповнення потрібна додаткова поїздка, і для цього потрібна додаткова робота в кеш-сервісі сервера, тому це трохи менш ефективно.

Загалом, вам слід віддавати перевагу WITHтимчасовим таблицям, якщо ви не знаєте, що отримаєте користь від створення індексу.

Однак інший варіант, підзапит у FROMпункті, має зовсім інший набір переваг. Зокрема, він може бути накреслений, і кваліфіковані особи можуть бути підтягнуті / відсунуті вниз. Про це я писав у недавній статті блогу .


Що з переглядами та тимчасовими поглядами?
CMCDragonkai

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