Cuidados a ter para ajudar na eliminação de joins em SQL Server

Há uns dias coloquei aqui um post sobre eliminação de joins e, sem querer, deparei-me hoje com uma situação onde parecia que o SQL Server não estava a fazer um bom trabalho.

Vai-se a ver… e quem não estava a fazer um bom trabalho éramos nós.

A situação era bem mais complicada do que esta, mas se pegarmos no código do último post é rápida de explicar.

Vamos lá de novo.

create table JoinEliminationDemo01
(
	id int identity primary key
,	Col1 uniqueidentifier 
)
go
insert into JoinEliminationDemo01
	(Col1)
select NEWID()
go 10


create table JoinEliminationDemo02
(
	id int identity primary key
,	id_ref int not null
,	Col1 uniqueidentifier
)
go
insert into JoinEliminationDemo02
	(id_ref, Col1)
select (ABS(CHECKSUM(NEWID()))%10)+1, NEWID()
from sys.objects a
cross join sys.objects b
go


ALTER TABLE JoinEliminationDemo02 
ADD CONSTRAINT 
  JoinEliminationDemo02__id_ref__id FOREIGN KEY(id_ref)
REFERENCES JoinEliminationDemo01 (id)

Imaginemos que neste caso queremos a Col1 da JoinEliminationDemo02 e do id da JoinEliminationDemo01.


É muito simples fazer este erro em queries mais complexas com uma mão-cheia de joins.

set statistics time, io on

select	a.Col1
	,	b.id
from JoinEliminationDemo02 a
inner join JoinEliminationDemo01 b
	on b.id = a.id_ref

Neste exemplo simples percebemos que a nossa execução está a tocar nas duas tabelas quando temos criada uma relação para evitar isso mesmo.

Facilmente chegamos à solução.

Estamos a retirar valores de uma e de outra tabela e, nestes casos, o SQL Server não consegue eliminar a referência.
Se formos buscar o valor que precisamos à JoinEliminationDemo02 o join deverá ser eliminado.

select	a.Col1
	,	a.id_ref
from JoinEliminationDemo02 a
inner join JoinEliminationDemo01 b
	on b.id = a.id_ref

Parece óbvio, mas nem sempre é.

Share

You may also like...

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *