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.
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.
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?