Como você descobriu com seu exists
exemplo, o SQL Server pode usar o fato de que uma chave estrangeira é confiável quando o plano de consulta é criado.
Há mais alguma coisa que eu perco usando o NOCHECK?
Além do fato de você poder adicionar valores a uma coluna que não deveria estar lá, conforme respondido por Ste Bov, você terá mais cenários em que o plano de consulta será melhor quando a chave estrangeira for confiável.
Aqui está um exemplo com uma exibição indexada .
Você tem duas tabelas com uma restrição FK confiável.
create table dbo.Country
(
CountryID int primary key,
Name varchar(50) not null
);
create table dbo.City
(
CityID int identity primary key,
Name varchar(50),
IsBig bit not null,
CountryID int not null
);
alter table dbo.City
add constraint FK_CountryID
foreign key (CountryID)
references dbo.Country(CountryID);
Não existem muitos países, mas um gazilhão de cidades e algumas delas são grandes cidades.
Dados de amostra:
-- Three countries
insert into dbo.Country(CountryID, Name) values
(1, 'Sweden'),
(2, 'Norway'),
(3, 'Denmark');
-- Five big cities
insert into dbo.City(Name, IsBig, CountryID) values
('Stockholm', 1, 1),
('Gothenburg', 1, 1),
('Malmoe', 1, 1),
('Oslo', 1, 2),
('Copenhagen', 1, 3);
-- 300 small cities
insert into dbo.City(Name, IsBig, CountryID)
select 'NoName', 0, Country.CountryID
from dbo.Country
cross apply (
select top(100) *
from sys.columns
) as T;
As consultas mais frequentemente executadas neste aplicativo estão relacionadas à localização do número de grandes cidades por país. Para acelerar as coisas, adicionamos uma exibição indexada.
create view dbo.BigCityCount with schemabinding
as
select count_big(*) as BigCityCount,
City.CountryID,
Country.Name as CountryName
from dbo.City
inner join dbo.Country
on City.CountryID = Country.CountryID
where City.IsBig = 1
group by City.CountryID,
Country.Name;
go
create unique clustered index CX_BigCityCount
on dbo.BigCityCount(CountryID);
Depois de um tempo, vem a demanda de adicionar um novo país
insert into dbo.Country(CountryID, Name) values(4, 'Finland');
O plano de consulta para essa inserção não apresenta surpresas.
![insira a descrição da imagem aqui](https://i.stack.imgur.com/HpfFB.png)
Uma inserção de índice em cluster na Country
tabela.
Agora, se sua chave estrangeira não era confiável
alter table dbo.City nocheck constraint FK_CountryID;
e você adiciona um novo país
insert into dbo.Country(CountryID, Name) values(5, 'Iceland');
você acabaria com essa imagem não tão bonita.
![insira a descrição da imagem aqui](https://i.stack.imgur.com/d7VWe.png)
A ramificação inferior existe para atualizar a exibição indexada. Ele faz uma varredura completa da tabela City
para descobrir se o país CountryID = 5
já possui linhas na tabela City
.
Quando a chave é confiável, o SQL Server sabe que não pode haver linhas City
que correspondam à nova linha Country
.
INSERT
uma nova linha relacionada a uma linha pai inexistente ou se você tentarDELETE
uma linha que tenha linhas filho posteriormente?