Freigeben über


Desafio: Cadê meu Join?

Dessa vez apresento um desafio curioso que recebi esses dias enquanto estava no escritório. Uma pessoa me apresentou uma consulta SQL que relacionava os dados de cliente com os endereços.

SELECT

c.*FROM Clientes c LEFT OUTERJOIN Regioes r
ON c.regiaoId = r.regiaoId AND
r.regiaoId ISNULL

O interessante é que o plano de execução gerada não possui JOIN entre tabelas. Surge a pergunta: CADÊ MEU JOIN???

image

O problema fica mais interessante quando substituimos o LEFT OUTER JOIN por um INNER JOIN, pois o plano de execução não apresenta a leitura em nenhuma tabela.

SELECT

c.*FROM Clientes c INNERJOIN Regioes r
ON c.regiaoId = r.regiaoId AND
r.regiaoId ISNULL

image

A pergunta desse Desafio Ninja é:

O que aconteceu com o Join de tabela e com a operação de Table Scan?

Poste sua opinião e resposta na seção de comentários.

 

Script usado:

CREATE TABLE Regioes (regiaoId INT PRIMARY KEY,    local VARCHAR(100) NOT NULL)CREATE TABLE Clientes  (id INT, nome VARCHAR(50), regiaoId INT FOREIGN KEY REFERENCES Regioes(regiaoId))

INSERT Regioes VALUES (1, 'Norte'), (2, 'Sul')INSERT Clientes VALUES (1, 'Cliente1', 1), (2, 'Cliente2', 1)GO

SELECT c.* FROM Clientes c LEFT JOIN Regioes r ON c.regiaoId = r.regiaoId AND r.regiaoId IS NULL

SELECT c.* FROM Clientes c INNER JOIN Regioes r ON c.regiaoId = r.regiaoId AND r.regiaoId IS NULL

Comments

  • Anonymous
    January 24, 2012
    Essa eu vi no PASS 2011 :) O SQL é esperto o suficiente para saber que já que eu defini que RegiaoID não pode ser NULO, então quando faço uma busca que foge uma FK ou uma check constraint (no caso "WHERE regiaoId IS NULL") o otimizador nem precisa ir na tabela para ter certeza que não vai retornar nenhuma linha ÓTIMO DESAFIO heehheehhe

  • Anonymous
    January 24, 2012
    É isso ai!!! Matou fácil fácil.. :)

  • Anonymous
    February 09, 2012
    Legal o desafio. Compartilho da resposta do Sérgio. Semana passada passei por um problema semelhante analisando um plano de execução e não sabia do que se tratava. Fui procurar quem "manja" do QO e falei com o Fabiano Amorim, e ele me passou o link de um artigo que ele escreveu exatamente sobre isto. O link é este: www.simple-talk.com/.../query-optimizer-and-cartesian-products Bacana! Abraços, Erickson Ricci

  • Anonymous
    February 12, 2012
    O desafio é bastante curioso e exemplifica parte do funcionamento inteligente do Query Optimizer (QO).

  • Anonymous
    May 21, 2012
    Grande Catae, este caso poderia ser considerado um contradiction na fase simplification ?

  • Anonymous
    May 23, 2012
    Exato! Você está 100% correto.

  • Anonymous
    May 23, 2012
    Obrigado pela conversa Laerte. Deixo explicar a quem eventualmente estiver lendo esse comentário: Laerte me fez a pergunta no blog e por MSN sobre o que seria "contradiction na fase de simplification". Na hora, respondi que não conhecia exatamente o termo de contradiction. Ele me passou algumas referencias para estudar e agora sei o que é isso. Valeu Laerte.

  • Anonymous
    July 19, 2012
    The comment has been removed

  • Anonymous
    July 25, 2012
    Com certeza, essa frase resume o comportamento do SQL Server: Não acredito que o SQL seja "esperto", mas sim que seja "prático", pois ele planeja a execução realizando a leitura das páginas de dados que serão utilizadas e apresenta o plano de execução executado para as tais leituras.

  • Anonymous
    March 14, 2013
    Muito interessante, não sabia dessa do otimizador...

  • Anonymous
    April 09, 2013
    E no caso do LEFT JOIN, como nenhuma coluna da tabela à direita foi usada, então o SQL não precisa fazer nenhuma leitura lá pois o resultado não vai impactar já que de qualquer maneira todas as linhas da tabela da esquerda serão retornadas. Agora o interessande disso é perceber tambem como o processaento lógico da query funciona... Se você colocar o filtro "r.regiaoId IS NULL"  na cláusula WHERE em vez da cláusula ON, as coisas mudam um pouquinho ... :) Acho que esse é bom exemplo pros desenvolvedores entenderem quando ON e WHERE podem trazer resultados diferentes.

  • Anonymous
    April 16, 2013
    É verdade, há uma diferença bem grande entre esses tipos de JOIN entre tabelas.