Comme vous l'avez découvert avec votre exists
exemple, SQL Server peut utiliser le fait qu'une clé étrangère est approuvée lors de la génération du plan de requête.
Y a-t-il autre chose que je perds en utilisant NOCHECK?
Mis à part le fait que vous pouvez ajouter des valeurs à une colonne qui ne devrait pas être là comme l'a répondu Ste Bov, vous aurez plus de scénarios où le plan de requête sera meilleur lorsque la clé étrangère est approuvée.
Voici un exemple avec une vue indexée .
Vous disposez de deux tables avec une contrainte FK approuvée.
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);
Il n'y a pas tant de pays que des millions de villes et certains d'entre eux sont de grandes villes.
Exemples de données:
-- 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;
Les requêtes les plus souvent exécutées dans cette application sont liées à la recherche du nombre de grandes villes par pays. Pour accélérer les choses, nous ajoutons une vue indexée.
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);
Après un certain temps vient la demande d'ajouter un nouveau pays
insert into dbo.Country(CountryID, Name) values(4, 'Finland');
Le plan de requête pour cet insert n'a aucune surprise.
Une insertion d'index cluster dans la Country
table.
Maintenant, si votre clé étrangère n'était pas fiable
alter table dbo.City nocheck constraint FK_CountryID;
et vous ajoutez un nouveau pays
insert into dbo.Country(CountryID, Name) values(5, 'Iceland');
vous vous retrouveriez avec cette image pas si jolie.
La branche inférieure est là pour mettre à jour la vue indexée. Il effectue une analyse complète du tableau City
pour déterminer si le pays avec CountryID = 5
possède déjà des lignes dans le tableau City
.
Lorsque la clé est approuvée, SQL Server sait qu'aucune ligne ne City
peut correspondre à la nouvelle ligne Country
.
INSERT
une nouvelle ligne qui se rapporte à une ligne parent inexistante ou si vous essayezDELETE
plus tard une ligne qui a des lignes enfants?