PostgreSQL ottimizza l'aggiunta di colonne con DEFAULT non NULL?


10

Quando si aggiungono NOT NULLcolonne con un DEFAULTvalore - PostgreSQL ottimizza questa operazione?

Nel caso in cui la tabella abbia n righe, un'alter-table-add-column non ottimizzata produrrebbe n scritture del valore predefinito - che potrebbe essere molto doloroso, ovviamente. Con l'ottimizzazione il DB creerebbe istantaneamente la nuova colonna, memorizzando solo una copia del valore predefinito che verrebbe restituito quando non viene trovato alcun valore non predefinito per quella colonna in una struttura di dati di indice adatta.

Ad esempio Oracle 11g ha una tale ottimizzazione .

Risposte:


16

Non esiste un tale meccanismo in PostgreSQL.

Tuttavia, è ancora possibile evitare gli effetti eccessivi di tale modifica della tabella.

La seguente istruzione acquisisce un blocco esclusivo dell'accesso sulla tabella per la durata dell'istruzione / transazione:

ALTER TABLE your_table
    ADD COLUMN new_column integer NOT NULL DEFAULT 0;

Questa istruzione modifica il catalogo, quindi riscrive l'intera tabella in modo che la nuova colonna contenga il valore predefinito in tutte le righe. Se la tabella ha molte righe e vi si accede abbastanza frequentemente, ciò causerebbe alcuni problemi temporanei.

Per evitarlo, prova a tenere il lucchetto esclusivo il più corto possibile:

ALTER TABLE your_table
    ADD COLUMN new_column integer;
ALTER TABLE your_table
    ALTER COLUMN new_column SET DEFAULT 0;

Poiché si tratta sostanzialmente di una (in realtà due) modifiche al catalogo (non avviene alcuna modifica dei dati), si completerà abbastanza velocemente. Quindi, a seconda delle esigenze e dell'utilizzo della tabella, è possibile aggiornare la nuova colonna al valore predefinito in un passaggio o in batch e, al termine, impostare la colonna su NOT NULL.

Aggiornamento su un desiderio che diventa realtà: PostgreSQL 11 avrà questa funzione. Vedi https://www.depesz.com/2018/04/04/waiting-for-postgresql-11-fast-alter-table-add-column-with-a-non-null-default/ per ulteriori informazioni.


4

Sì, con PostgreSQL 11

Questa funzione è nuova e disponibile nella versione 11.

ALTER TABLE your_table
    ADD COLUMN new_column integer NOT NULL DEFAULT 0;

Quanto sopra è uno di questi comandi che saranno interessati da questa ottimizzazione; ma, va detto che nonNOT NULL è richiesto. Ogni nuova colonna aggiunta con un valore predefinito non nullo è ora ottimizzata. Puoi trovare la voce in questo commitfest Dovresti anche dare un'occhiata a questo fantastico articolo a riguardo, "Un collegamento mancante in Postgres 11: Creazione rapida di colonne con valori predefiniti" .

Soluzione alternativa a Pre-PostgreSQL 11

Se stai cercando di evitare l'esclusivo blocco del tavolo sul tavolo, segui i consigli di Craig Ringer,

  • Aggiungi una colonna senza a DEFAULT
  • ALTERper aggiungere il DEFAULTsuccessivo in modo che si applichi alle righe appena inserite
  • Quindi popolare la nuova colonna su righe esistenti da lotti progressivi UPDATEs
  • Quando tutte le righe hanno il valore, aggiungi il NOT NULLvincolo
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.