Come hai scoperto con il tuo exists
esempio, SQL Server può utilizzare il fatto che una chiave esterna è attendibile quando viene creato il piano di query.
C'è qualcos'altro che perdo usando NOCHECK?
A parte il fatto che è possibile aggiungere valori a una colonna che non dovrebbe essere lì come ha risposto Ste Bov, si avranno più scenari in cui il piano di query sarà migliore quando la chiave esterna è attendibile.
Ecco un esempio con una vista indicizzata .
Hai due tabelle con un vincolo FK attendibile.
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);
Non ci sono così tanti paesi, ma un gazillion di città e alcuni di loro sono grandi città.
Dati di esempio:
-- 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;
Le query eseguite più spesso in questa applicazione sono legate alla ricerca del numero di grandi città per paese. Per accelerare le cose con ciò aggiungiamo una vista indicizzata.
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);
Dopo un po 'arriva la richiesta di aggiungere un nuovo paese
insert into dbo.Country(CountryID, Name) values(4, 'Finland');
Il piano di query per quell'inserto non presenta sorprese.
Un indice cluster inserito nella Country
tabella.
Ora, se la tua chiave esterna non era attendibile
alter table dbo.City nocheck constraint FK_CountryID;
e aggiungi un nuovo paese
insert into dbo.Country(CountryID, Name) values(5, 'Iceland');
finiresti con questa foto non così bella.
Il ramo inferiore è lì per aggiornare la vista indicizzata. Esegue una scansione completa della tabella City
per capire se il paese con CountryID = 5
ha già delle righe nella tabella City
.
Quando la chiave è attendibile, SQL Server sa che non ci possono essere righe City
che corrispondano alla nuova riga in Country
.
INSERT
una nuova riga correlata a una riga padre inesistente o se provi inDELETE
seguito una riga con righe figlio?