web-dev-qa-db-fra.com

PostgreSQL: Pourquoi créer une table aussi plus rapide que Créer ... Insérez-vous?

Vous trouverez ci-dessous les deux syntaxes différentes pour la même chose.

  1. Avec un COPY TABLE AS SELECT (CTAS).

    CREATE TABLE main
    AS
      SELECT *
      FROM other;
    
  2. Comme des déclarations distinctes avec CREATE TABLE et INSERT INTO

    CREATE TABLE main (like other);
    
    INSERT INTO main
    SELECT *
    FROM other;
    

J'ai observé que les CTA sont plus rapides que distincts CREATE TABLE .. INSERT. Le premier prend 20 secondes pour terminer l'exécution. La deuxième syntaxe deux prend 1 min 15 secondes à une exécution complète.

Quelle pourrait être la raison de la différence?

3
user2274074

CREATE TABLE AS présente des avantages par rapport à l'autre formulaire, à savoir - réduction ou élimination du WAL. . Certainement optimisations peuvent être appliquées à quelques commandes (à savoir. CREATE TABLE AS, CREATE INDEX, CLUSTER, COPY into tables créées ou tronquées dans la même transaction) dans certains modes de réduction de WAL (minimum).

En niveau minimal, la journalisation WAL de certaines opérations en vrac peut être ignorée en toute sécurité, ce qui peut rendre ces opérations beaucoup plus rapidement (voir la section 14.4.7).

Mais Minimal WAL ne contient pas suffisamment d'informations pour reconstruire les données d'une sauvegarde de base et des journaux WALL, de sorte que la réplique ou supérieure doit être utilisée pour activer l'archivage WAL (archive_mode) et la diffusion en continu.

Vous pouvez lire plus d'informations à ce sujet ici

14.4.7. Désactiver la réplication de l'archivage WAL et du streaming

Lors du chargement de grandes quantités de données dans une installation qui utilise une réplication d'archivage WAL ou de diffusion en continu, elle peut être plus rapide de prendre une nouvelle sauvegarde de base après la charge de la charge que de traiter une grande quantité de données WAL incrémentielles. pour empêcher la journalisation de WAL incrémentielle lors du chargement, désactivez l'archivage et la diffusion en continu, en définissant wal_level au minimum, archive_mode à OFF, et max_wal_senders à zéro. Mais noter que la modification de ces paramètres nécessite un redémarrage du serveur.

En plus d'éviter le temps de l'archiveur ou de l'expéditeur WAL de traiter les données WAL, cela fera que cela rendra certaines commandes plus rapidement, car elles sont conçues pour ne pas écrire WAL du tout si Wal_level est minime. (Ils peuvent garantir la sécurité des crash plus à moindre coût en faisant un FSYNC à la fin que par écrit WALL.)

En tant que note spéciale, si vous revenez à votre

CREATE TABLE t1 (like t2);

Et plutôt faire

CREATE TABLE UNLOGGED t1 (like t2);

Ce sera encore plus rapide. Mais ne faites pas cela comme vous manquerez WALL. Pour plus d'informations sur cette lecture

3
Evan Carroll