Dado o banco de dados StackOverflow2010, criei algumas chaves estrangeiras para explorar a eliminação de junções:
Chave Estrangeira 1 - Todos os comentários devem ter uma postagem
Excluir comentários sem uma postagem
DELETE c
FROM Comments c
LEFT JOIN Posts p
ON c.PostId = p.Id
WHERE p.Id IS NULL
crie a chave estrangeira
ALTER TABLE Comments
ADD CONSTRAINT fk_Comments_PostId
FOREIGN KEY (PostId) REFERENCES Posts(Id)
Agora podemos executar a consulta abaixo e ver a eliminação da junção:
SELECT c.Id
FROM Comments c
JOIN Posts p
ON p.Id = c.PostId
o plano está aqui e mostra como eu esperaria, que apenas a tabela de comentários é lida
Chave Estrangeira 2 - Todas as postagens devem ter um usuário proprietário
Ao contrário do que foi dito acima, se eu redefinir as coisas e tentar com a seguinte chave estrangeira, não vejo a eliminação da junção:
Excluir postagens sem um OwnerUser
DELETE p
FROM Posts p
LEFT JOIN Users u
ON p.Owneruserid = u.id
WHERE u.Id IS NULL
Crie a chave estrangeira
ALTER TABLE Posts
ADD CONSTRAINT fk_Posts_UserId
FOREIGN KEY (OwnerUserId) REFERENCES Users(Id)
Execute minha consulta
SELECT p.Id
FROM Posts p
JOIN Users u
ON p.OwnerUserId = u.Id
o plano mostra que o SQL Server acessa ambas as tabelas.
Por que a chave estrangeira 2 não se beneficia da eliminação de junção, mas a chave estrangeira 1 sim?
A coluna OwnerUserId em Postagens permite nulos. A coluna PostId em Comentários não.
Quaisquer valores nulos em OwnerUserId resultarão na eliminação da linha Postagens pelo predicado de junção, que rejeita nulos:
Portanto, a junção pode afetar os resultados e não pode ser eliminada.
Você precisa filtrar os nulos explicitamente (resultando em um conjunto incompleto de linhas de Posts ) ou usar uma junção externa para ver a eliminação da tabela:
Perguntas relacionadas