AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 267947
Accepted
John Bachir
John Bachir
Asked: 2020-05-27 18:40:48 +0800 CST2020-05-27 18:40:48 +0800 CST 2020-05-27 18:40:48 +0800 CST

Como posso definir uma coluna como NOT NULL sem bloquear a tabela durante uma verificação de tabela?

  • 772

(A pergunta anterior era: o Postgres usará um índice de várias colunas ao definir várias colunas não nulas?)


Normalmente, quando defino uma coluna como não nula, se ela não tiver um índice, eu a adiciono primeiro, para que o postgres possa (espero) usar o índice enquanto faz a varredura da tabela enquanto bloqueia a tabela, para que a tabela seja bloqueada por um menor período de tempo.

Eu quero definir várias colunas não nulas, assim:

alter table foos
  alter column bar1 set not null
  alter column bar2 set not null
  alter column bar3 set not null
  alter column bar4 set not null;

Se eu fizer um índice de várias colunas para essas colunas, o postgres o usará ao verificar a tabela bloqueada antes de fazer essa alteração?

CREATE INDEX CONCURRENTLY my_index on foos (bar1, bar2, bar3, bar4);

E se eu fizer um índice parcial em IS NULL (ou IS NOT NULL)

CREATE INDEX CONCURRENTLY my_index on foos (bar1, bar2, bar3, bar4) where bar1 is null and bar2 is null and bar3 is null and bar4 is null;
postgresql index
  • 2 2 respostas
  • 2861 Views

2 respostas

  • Voted
  1. Best Answer
    Melkij
    2020-05-30T05:01:34+08:002020-05-30T05:01:34+08:00

    Outra resposta de outro colaborador do postgresql.

    O PostgreSQL nem tentará usar nenhum índice durante a execução de "alter table set not null". Simplesmente não é implementado.

    A implementação adequada da verificação de índice é uma parte difícil. Não podemos simplesmente fazer algo como esta consulta

    select exists(select from foos where bar1 is null)
    

    do comando alter table por várias razões . Esse recurso exigirá um grande pedaço de código (e, provavelmente, código frágil em alguns casos extremos), muito trabalho, apenas para casos de uso limitados. Algo que os desenvolvedores não gostam. Na verdade, a comunidade pgsql-hackers não gosta de como NOT NULL é armazenado no catálogo do sistema. Ficaria mais limpo com um redesenho desta parte do catálogo. Depois disso, seria possível fazer SET NOT NULL NOT VALID com um bloqueio curto e validação de tabela sem um bloqueio exclusivo. Semelhante a alter table .. add constraint ... not valid+ alter table .. validate constraintpara restrição de verificação ou chave estrangeira. Mas esse redesenho é muito mais trabalhoso, e não há quem queira fazê-lo.

    Mas tenho uma boa notícia: no PostgreSQL 12 (e acima) escanear a tabela inteira não é a única opção. alter table set not nullpode provar a correção de NOT NULL por restrições de verificação existentes. Assim, pode-se fazer:

    -- short-time exclusive lock
    alter table foos 
      add constraint foos_not_null 
      check (bar1 is not null) not valid;
    
    -- seqscan, but without exclusive lock, concurrent sessions can read/write
    alter table foos validate constraint foos_not_null;
    
    -- exclusive lock, but foos_not_null proves: there is no NULL in this column
    -- so this alter table would be fast
    alter table foos alter column bar1 set not null;
    -- not needed anymore
    alter table foos drop constraint foos_not_null;
    

    Esse foi o meu patch . Sim, isso parece uma solução alternativa. Mas, felizmente, ele foi mesclado e agora é possível set not nullsem um longo bloqueio exclusivo.

    • 16
  2. Laurenz Albe
    2020-05-27T22:16:16+08:002020-05-27T22:16:16+08:00

    Observei o código-fonte (função ATRewriteTableem src/backend/commands/tablecmds.c), e o PostgreSQL sempre usa uma varredura sequencial da tabela para verificar as NOT NULLrestrições.

    Portanto, criar índices não acelerará a execução.

    • 4

relate perguntas

  • Quanto "Padding" coloco em meus índices?

  • Sequências Biológicas do UniProt no PostgreSQL

  • O que significa "índice" em RDBMSs? [fechado]

  • Como criar um índice condicional no MySQL?

  • Qual é a diferença entre a replicação do PostgreSQL 9.0 e o Slony-I?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve