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?