Exemplo pratico de utilização do comando MERGE

Um amigo meu veio me perguntar sobre algumas duvidas em relação ao comando MERGE do SQL Server, principalmente em relação a performance e sua utilização.

Abaixo segue o script que o enviei, assim como o ajudou, espero que possa ajudar outras pessoas tambem.

CREATE TABLE Funcionarios
(
	nm_Funcionario VARCHAR(100),
	pct_Comissao INT
)

CREATE TABLE Funcionarios2
(
	nm_Funcionario VARCHAR(100),
	pct_Comissao INT
)

CREATE TABLE LogTeste
(
	nm_Funcionario VARCHAR(100),
	Texto VARCHAR(100)
)

INSERT INTO Funcionarios VALUES
('Fabrizzio', 5),
('Caputo', 10),
('Antoniaci', 15)

INSERT INTO Funcionarios2 VALUES
('Giovanni', 5),
('Caputo', 20),
('Antoniaci', 25)



--Antes
SELECT * FROM Funcionarios
/*
Fabrizzio	5
Caputo		10
Antoniaci	15
*/

SELECT * FROM Funcionarios2
/*
Giovanni	5
Caputo		20
Antoniaci	25
*/

MERGE Funcionarios AS Target
USING (SELECT nm_Funcionario, pct_Comissao FROM Funcionarios2) As Source(Nome, Comissao)
ON (Target.nm_Funcionario = Source.Nome)
WHEN MATCHED THEN
	UPDATE SET Target.pct_Comissao = Source.Comissao
WHEN NOT MATCHED THEN
	INSERT (nm_Funcionario, pct_Comissao)
	VALUES (Source.Nome, Source.Comissao);
	
--DEPOIS
--Antes
SELECT * FROM Funcionarios
/*
Fabrizzio	5
Caputo		20
Antoniaci	25
Giovanni	5
*/

SELECT * FROM Funcionarios2
/*
Giovanni	5
Caputo	20
Antoniaci	25
*/

/*EM RELAÇÃO AO QUE FAZ

O merge é comando muito bom, disponivel (Se não me engano) desde o SQL Server 2005, o proposito dele é enxugar codificação
aonde com apenas um comando, voce consegue fazer N ações, como no exemplo acima que eu fiz:
	- Caso o funcionario não exista na tabela "Funcionario", o mesmo sera inserido.
	- Caso o mesmo ja exista, o pct_Comissao sera atualizado
Alem disso, é bem flexivel, a ponto de eu conseguir especificar algumas regras como:
	- Só atualize se o pct_Comissao for mais baixo
	- Atualize o Target ou o Source
	- Faça Match pelo Target ou Source ao invez de um match generico
O "problema" é que ele realmente não é dos comandos mais simples, alem de ter muitas opções, o que acaba confundindo muitas 

pessoas,
alem de algumas restrições que o fazem ser menos utilizado.

 EM RELAÇÃO A PERFORMANCE

O que meu codigo fez:
	- Inseriu novos e atualizou os ja existentes

No merge: 0,028126 de custo 
Sem merge: 0.0468959 de custo (Soma dos 2 abaixo)
Ou seja, houve sim uma queda de performance e o Merge se mostrou melhor.
Mas lembrando que performance é algo complicado e depende de indices, que por sua vez depende do percentual de atendimento 

condicional
em relação ao todo e algumas outras coisas.....
(Lembrando que estamos falando de uma tabela com 3 registros)
*/
--INSERIR NOVOS
INSERT INTO Funcionarios
SELECT b.nm_Funcionario, b.pct_Comissao
FROM Funcionarios a
RIGHT JOIN Funcionarios2 b
	ON (a.nm_Funcionario = b.nm_Funcionario)
WHERE a.nm_Funcionario IS NULL
--0,0300194
--ATUALIZAR ANTIGOS
UPDATE a
SET a.pct_Comissao = b.pct_Comissao
FROM Funcionarios a
INNER JOIN Funcionarios2 b
	ON (a.nm_Funcionario = b.nm_Funcionario)
--0,0168765

SELECT 0.0300194 + 0.0168765

Anúncios
Post a comment or leave a trackback: Trackback URL.

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: