PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Dados redundantes em declarações de atualização


Devido ao PostgreSQL MVCC, um UPDATE é efetivamente muito parecido com um DELETE mais um INSERT . Com a notável exceção dos valores torrados - veja:
  • O Postgres reescreve a linha inteira na atualização?

(E pequenas diferenças para tuplas somente de heap - DELETE + INSERT inicia uma nova cadeia HOT - mas isso não tem relação com o caso em questão.)

Para ser preciso, a linha "excluída" é invisível para qualquer transação iniciada após a confirmação da exclusão e limpa posteriormente. Portanto, no lado do banco de dados, incluindo manipulação de índice, não há nenhuma diferença entre as duas afirmações. (Exceções se aplicam, continue lendo.) Aumenta um pouco o tráfego de rede (dependendo dos seus dados) e precisa de um pouco de análise.

Estudei as atualizações HOT um pouco mais após a entrada de @araqnid e fiz alguns testes. Atualizações em colunas que não alteram o valor não fazem diferença qualquer coisa no que diz respeito às atualizações HOT. Minha resposta se mantém. Veja os detalhes abaixo.

Isso também se aplica a atributos torrados, pois eles também não são tocados, a menos que os valores realmente mudem .

No entanto , se você usar acionadores por coluna (introduzido na página 9.0), isso pode ter efeitos colaterais indesejados!

Cito o manual sobre gatilhos:

... um comando como UPDATE ... SET x = x ... irá disparar um gatilho na coluna x , mesmo que o valor da coluna não tenha sido alterado .

Minha ênfase em negrito.

As camadas de abstração são por conveniência. Eles são úteis para desenvolvedores analfabetos em SQL ou se o aplicativo precisar ser portátil entre diferentes RDBMS. No lado negativo, eles podem prejudicar o desempenho e introduzir pontos adicionais de falha. Evito-os sempre que possível.

Atualizações HOT (tupla somente heap)


Tuplas somente de pilha foram introduzidas com o Postgres 8.3, com melhorias importantes em 8.3.4 e 8.4.9.
As notas de lançamento do Postgres 8.3:

UPDATE s e DELETE s deixam tuplas mortas para trás, assim como falha INSERT s.Anteriormente apenas VACUUM poderia recuperar o espaço ocupado por tuplas mortas. WithHOT dead tuple space pode ser recuperado automaticamente no momento de INSERT ou UPDATE se nenhuma alteração for feita nas colunas indexadas . Isso permite um desempenho mais consistente. Além disso, o HOT evita adicionar entradas de índice duplicadas.

Destaque meu. E "sem alterações" inclui casos em que as colunas são atualizadas com o mesmo valor que já possuem. Eu realmente testei , como eu não tinha certeza.

Em última análise, o extenso README.HOT no código-fonte confirma isso.

Colunas torradas também não atrapalham as atualizações HOT. A tupla atualizada por HOT apenas vincula-se à(s) mesma(s) tupla(s) inalterada(s) na bifurcação de brinde da relação. As atualizações HOT funcionam até mesmo com valores torrados na lista de destino (na verdade alterados ou não). Se os valores torrados forem alterados, isso acarretará gravações no fork da relação torrada, obviamente. Testei tudo isso também.

Não acredite na minha palavra, veja por si mesmo. O Postgres fornece algumas funções para verificar estatísticas. Execute seu UPDATE com e sem todas as colunas e verifique se faz alguma diferença.
-- Number of rows HOT-updated in table:
SELECT pg_stat_get_tuples_hot_updated('table_name'::regclass::oid)

-- Number of rows HOT-updated in table, in the current transaction:
SELECT pg_stat_get_xact_tuples_hot_updated('table_name'::regclass::oid)

Ou use pgAdmin. Selecione sua tabela e inspecione a guia "Estatísticas" na janela principal.

Esteja ciente de que as atualizações HOT só são possíveis quando há espaço para a nova versão da tupla na mesma página do fork de relação principal. Uma maneira simples de forçar essa condição é testar com uma pequena tabela que contém apenas algumas linhas. O tamanho da página é normalmente 8k, portanto, deve haver espaço livre na página.