Expressions communes des tables PostgreSQL vs une table temporaire?


11

La documentation PostgreSQL sur WITH montre l'exemple suivant:

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;

Il note également:

Une propriété utile des requêtes WITH est qu'elles ne sont évaluées qu'une seule fois par exécution de la requête parent, même si elles sont référencées plusieurs fois par la requête parent ou les requêtes WITH avec frère.

Je vois que cela WITHpeut être utilisé pour d'autres choses, comme une évaluation récursive. Mais dans l'exemple ci-dessus, y a-t-il une différence importante entre l'utilisation WITHet la création de tables temporaires?


lorsque vous utilisez CTE pour créer la requête, l'ajout d'une autre colonne dans SELECTin ne WITHfait que taper le nom et la relancer. Alors qu'avec une table temporaire, il faudrait DROPet CREATE. D'un autre côté, si vous construisez une requête et que vous allez réutiliser des données statiques de nombreuses fois - la construction d'une table temporaire avec des index est certainement bénéfique contre CTE.
Vao Tsun

@VaoTsun si vous utilisez TEMPORARY TABLEavec ON COMMIT DROPdans une requête, il suffit également de modifier la requête et de la relancer, non? postgresql.org/docs/9.6/static/sql-createtable.html
Nathan Long

Réponses:


15

Il y a quelques différences subtiles, mais rien de radical:

  • Vous pouvez ajouter des index sur une table temporaire;
  • Les tables temporaires existent pour la durée de la session (ou, si ON COMMIT DROP, transaction), alors que la portée WITHest toujours strictement limitée à la requête;
  • Si une requête appelle une fonction / procédure, elle peut voir la table temporaire, mais elle ne peut voir aucune WITHexpression de table;
  • Une table temporaire génère du VACUUMtravail sur les catalogues système qui WITHne le fait pas, elle a besoin d'un aller-retour supplémentaire pour le créer / remplir, et elle nécessite un travail supplémentaire dans la gestion du cache du serveur, donc elle est légèrement moins efficace.

Dans l'ensemble, vous devriez préférer les WITHtables temporaires, sauf si vous savez que vous bénéficierez de la création d'un index.

Cependant, l'autre option, une sous-requête de la FROMclause, présente un ensemble d'avantages très différent. Il peut être en ligne, en particulier, et les qualificatifs peuvent être tirés vers le haut / bas. J'ai écrit à ce sujet dans un récent article de blog .


Qu'en est-il des vues et des vues temporaires?
CMCDragonkai

1
Un peu entre les deux, mais plus proche d'une table temporaire qu'un terme CTE. Pas d'index. Étendue de la session. Visible pour les fonctions / procédures. Besoin d'un aspirateur de catalogue.
Craig Ringer
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.