Tenho procurado muito por esse tipo de comparação ou algum tipo de equilíbrio de desempenho.
O que sei até agora é o seguinte:
MERGE é um comando T-SQL que já está implementado no SQL Server. Até onde eu sei, ele funciona muito bem, pois usa "mais ou menos " mapeamento de hash INNER JOIN para inserir e atualizar, mas tenho tido alguns problemas ao excluir na mesma instrução MERGE também ao usar CLUSTERED INDEX . Além disso, é muito rápido e permite que eu faça algumas cláusulas de comparação antes de atualizar ou inserir algo, por isso é muito flexível para mim.
No SQL Server, alguns cenários específicos preferem usar UPDATE e INSERT como instruções separadas e eu não discutiria isso. Em minha curta experiência, eu usaria MERGE por padrão como padrão para meu código.
Agora como DBA, estou enfrentando um novo desafio, tenho que gerenciar servidores MySQL também, então acabei procurando um comportamento MERGE semelhante no MySQL para melhorar o desempenho das consultas. Até agora, não encontrei nada parecido, mas INSERT ... ON DUPLICATE KEY ... UPDATE . Ainda assim, tenho algumas dúvidas de desempenho, pois não tenho certeza de como ele se comporta com o servidor, como funciona e se um par opcional de instruções funcionaria melhor ou mais rápido do que isso.
Procurando no MySQL, encontrei UPDATE + INSERT IGNORE , UPDATE + INSERT , INSERT ... REPLACE e assim por diante.
A documentação do MySQL é um pouco confusa ao tentar determinar se eu poderia usar algumas outras cláusulas ex. na instrução MERGE eu poderia usar AND (TARGET.COLUMN_X > 'VALUE') :
MERGE _TABLE A_ AS TARGET WITH _TABLE B_ AS SOURCE ON (TARGET.KEY = SOURCE.KEY) WHEN MATCHED AND (TARGET.COLUMN_X > 'VALUE') UPDATE TARGET.COLUMN_A = SOURCE.COLUMN_A ...
Não encontro como fazer isso no MySQL.
*CONSIDERAÇÃO
Eu tenho que administrar isso para obter melhor resultado de tempo e desempenho amigável.
O que tenho como configuração:
PERCONA MySQL
- txt que precisa ser carregado em uma tabela a cada mês com novos dados e algumas alterações (é por isso que estou procurando uma declaração semelhante a MERGE )
- Mecanismo InnoDB MySQL
- Tabelas de banco de dados relacional, portanto, não posso excluir ou truncar a tabela de destino porque todas elas estão relacionadas.
IODKU é a melhor das opções no MySQL. Funciona mais ou menos assim:
UNIQUE
chave (possivelmente clustered, unique,PRIMARY KEY
) para localizar a linha a ser modificada.INSERT
.UPDATE
.Você não pode ficar mais rápido do que isso.
Observe que a etapa 1 armazenará em cache tudo o que for necessário para #2 ou #3 no buffer_pool. (Bem, OK, os índices secundários são tratados de maneira 'atrasada' por meio do "Change Buffer".)
Observe ainda que a instrução é atômica, enquanto suas alternativas de 2 instruções precisam estar em uma transação.
Lembre-se de que
REPLACE
éDELETE
(0, 1 ou possivelmente várias linhas, se você tiver várias chaves exclusivas), entãoINSERT
. Observe que oAUTO_INCREMENT
valor (se usado) é descartado e um novo é criado.Quanto àquela consulta confusa, provavelmente pode ser feita com
GREATER()
e/ouIF()
e/ouVALUES()
. Supondo que você esteja tentando mesclar várias linhas, você precisa da sintaxe IODKU+SELECT:Como não sei o que o MERGE faz, não posso fornecer todos os detalhes.