O PostgreSQL otimiza a adição de colunas com padrões não nulos?


10

Ao adicionar NOT NULLcolunas com um DEFAULTvalor - o PostgreSQL otimiza esta operação?

Caso a tabela tenha n linhas, uma coluna alter-add-table-non-optimizada produziria n gravações do valor padrão - o que poderia ser muito doloroso, obviamente. Com a otimização, o banco de dados criaria instantaneamente a nova coluna, armazene apenas uma cópia do valor padrão que seria retornado quando nenhum valor não padrão fosse encontrado para essa coluna em uma estrutura de dados de índice adequada.

Por exemplo, o Oracle 11g tem essa otimização .

Respostas:


16

Não existe esse mecanismo no PostgreSQL.

No entanto, você ainda pode evitar os efeitos excessivos dessa alteração de tabela.

A instrução a seguir adquire um bloqueio exclusivo de acesso na tabela pela duração da instrução / transação:

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

Essa instrução altera o catálogo e, em seguida, reescreve a tabela inteira para que a nova coluna contenha o valor padrão em todas as linhas. Se a tabela tiver muitas linhas e for acessada com frequência suficiente, isso causaria alguns problemas temporários.

Para evitá-lo, tente manter o bloqueio exclusivo o mais curto possível:

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

Como isso é basicamente apenas uma alteração (na verdade duas) do catálogo (nenhuma alteração de dados acontece), ela será concluída rapidamente. Em seguida, dependendo das suas necessidades e uso da tabela, você pode atualizar a nova coluna para o padrão em uma etapa ou em lotes e, quando terminar, definir a coluna como NOT NULL.

Atualização sobre um desejo se tornando realidade: o PostgreSQL 11 terá esse recurso. Consulte https://www.depesz.com/2018/04/04/waiting-for-postgresql-11-fast-alter-table-add-column-with-a-non-null-default/ para obter mais informações.


4

Sim, com o PostgreSQL 11

Esse recurso é novo e chegou à versão 11.

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

O acima é um desses comandos que será afetado por essa otimização; mas, deve-se dizer que nãoNOT NULL é necessário. Qualquer nova coluna adicionada com um padrão não nulo é otimizada agora. Você pode encontrar a entrada neste commitfest Você também deve verificar este excelente artigo sobre o assunto, "Um link ausente no Postgres 11: criação rápida de colunas com padrões" .

Solução alternativa pré-PostgreSQL 11

Se você está tentando evitar o bloqueio exclusivo da mesa, siga os conselhos de Craig Ringer,

  • Adicione uma coluna sem um DEFAULT
  • ALTERpara adicionar DEFAULTdepois para que se aplique às linhas recém-inseridas
  • Em seguida, preencha a nova coluna nas linhas existentes por lote progressivo UPDATEs
  • Quando todas as linhas têm o valor, você adiciona a NOT NULLrestrição
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.