Dica rápida – Removendo NOT IN

Dica rápida – Removendo NOT IN

Tempo de leitura: 2 minutos

Ola Galera, blz? Tô passando pra realizar um post na “velocidade da luz” devido ao curto espaço de tempo pra postar. Porém, essa duvida é meio que corriqueira no ambiente de desenvolvimento que passei. Quando temos um NOT IN, como podemos reescrever uma query? As vezes se soubermos como reescrever uma query de uma outra maneira e ela traz o mesmo resultado podemos obter ganho de performance. Mas, isso deve sempre ser testado para verificar se o ganho é verdadeiro(Esse assunto fica pra um outro post).

O Gustavo Maia escreveu um ótimo artigo sobre o assunto: http://gustavomaiaaguiar.wordpress.com/2009/01/18/piores-praticas-utilizacao-do-operador-not-in/

Evite usar o operador NOT IN para verificar inexistência de dados em tabelas. Se o uso deste operador for mesmo necessário, ele pode ser modificado por um left join, conforme Exemplo:

USE tempdb
go

IF EXISTS(SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(‘[dbo].[TB_CLIENTE]’) and type=’U’)

DROP TABLE [dbo].[TB_CLIENTE]

go

CREATE TABLE [dbo].[TB_CLIENTE] (COD int identity, NOME varchar(max))

go

INSERT INTO [dbo].[TB_CLIENTE](NOME)VALUES(‘Minha CONSULTORIA’)

INSERT INTO [dbo].[TB_CLIENTE](NOME)VALUES(‘Minha’)

INSERT INTO [dbo].[TB_CLIENTE](NOME)VALUES(‘Consultoria’)

GO

IF EXISTS(SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(‘[dbo].[TB_PEDIDO]’) and type=’U’)

DROP TABLE [dbo].[TB_PEDIDO]

go

CREATE TABLE [dbo].[TB_PEDIDO] (COD int identity, PRODUTO varchar(50), COD_CLI INT)

go

INSERT INTO [dbo].[TB_PEDIDO] (PRODUTO,COD_CLI)VALUES(‘NOTE BOOK’,1)

INSERT INTO [dbo].[TB_PEDIDO] (PRODUTO,COD_CLI)VALUES(‘CADERNO ESCOLAR’,1)

INSERT INTO [dbo].[TB_PEDIDO] (PRODUTO,COD_CLI)VALUES(‘REVISTA’,1)

INSERT INTO [dbo].[TB_PEDIDO] (PRODUTO,COD_CLI)VALUES(‘BICLICLETA’,2)

INSERT INTO [dbo].[TB_PEDIDO] (PRODUTO,COD_CLI)VALUES(‘TELEFONE CELULAR’,2)

INSERT INTO [dbo].[TB_PEDIDO] (PRODUTO,COD_CLI)VALUES(‘BOLA DE FUTEBOL’,2)

O script acima cria uma tabela de cliente e de pedidos. Imagine que você precisa retornar uma query que traz os clientes que NÃO tem pedidos. O pensamento inicial seria usar o NOT IN:

SELECT c.cod,c.nome FROM dbo.TB_CLIENTE c WHERE c.cod NOT IN (SELECT p.cod_cli FROM dbo.tb_pedido p)

O resultado seria:

A query poderia ser facilmente modificada para usar um left join obtendo o mesmo resultado.

 SELECT c.cod,c.nome, p.COD,p.COD_CLI FROM dbo.TB_CLIENTE c 
LEFT JOIN dbo.tb_pedido p 
on c.cod = p.cod_cli
where p.COD_CLI is null

Na velocidade da luz….rs.

Espero ter ajudado

 

3 comentários

  1. […] galera. blz? Em um dos meus artigos  anteriores eu mostrei como trocar o uso do NOT IN para o  Left JOIN(Link), porém, porque fizemos […]

  2. Renato Gomes disse:

    O mesmo vale para NOT EXISTS?

Deixe uma resposta

%d blogueiros gostam disto: