Há alguns dias em conversa com um colega referi o termo “join elimination” e ele ficou um pouco surpreendido.
Importa referir que a especialidade dele não é SQL e que é fenomenal em coisas que eu pouco entendo também. A famosa máxima “todos somos ignorantes, apenas em coisas diferentes”.
Vamos ver uma das maneiras mais simples de join elimination que o SQL Server trata com muito carinho.
Vamos lá criar aquelas tabelas que crio só para estas coisas.
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
Ficámos com uma tabela com id entre 1 e 10 e na outra temos o id_ref que apenas tem valores entre os valores da coluna id da primeira tabela.
Caso clássico para uma relação… e se não nos lembrarmos de colocar a foreign key?
set statistics time, io on
select a.id
, a.Col1
from JoinEliminationDemo02 a
inner join JoinEliminationDemo01 b
on b.id = a.id_ref



Quantas linhas retornámos? Claro, todas as da JoinEliminationDemo02.
E se nos lembrarmos?
ALTER TABLE JoinEliminationDemo02
ADD CONSTRAINT
JoinEliminationDemo02__id_ref__id FOREIGN KEY(id_ref)
REFERENCES JoinEliminationDemo01 (id)
select a.id
, a.Col1
from JoinEliminationDemo02 a
inner join JoinEliminationDemo01 b
on b.id = a.id_ref


Não toca na JoinEliminationDemo01. Não faz nenhum tipo de join. Não se queixa da “falta” de um índice.
Ajuda ou não ajuda?