Wie Sie in Ihrem exists
Beispiel festgestellt haben , kann SQL Server die Tatsache verwenden, dass ein Fremdschlüssel beim Erstellen des Abfrageplans vertrauenswürdig ist.
Gibt es noch etwas, das ich durch die Verwendung von NOCHECK verliere?
Abgesehen von der Tatsache, dass Sie einer Spalte Werte hinzufügen können, die nicht vorhanden sein sollten, wie von Ste Bov beantwortet, gibt es mehr Szenarien, in denen der Abfrageplan besser ist, wenn dem Fremdschlüssel vertraut wird.
Hier ist ein Beispiel mit einer indizierten Ansicht .
Sie haben zwei Tabellen mit einer vertrauenswürdigen FK-Einschränkung.
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);
Es gibt nicht so viele Länder, aber eine Unmenge von Städten, und einige von ihnen sind große Städte.
Beispieldaten:
-- 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;
Die am häufigsten ausgeführten Abfragen in dieser Anwendung beziehen sich auf die Ermittlung der Anzahl der Großstädte pro Land. Um dies zu beschleunigen, fügen wir eine indizierte Ansicht hinzu.
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);
Nach einer Weile kommt die Forderung, ein neues Land hinzuzufügen
insert into dbo.Country(CountryID, Name) values(4, 'Finland');
Der Abfrageplan für diese Einfügung enthält keine Überraschungen.
Eine gruppierte Indexeinfügung in die Country
Tabelle.
Nun, wenn Ihr Fremdschlüssel nicht vertrauenswürdig war
alter table dbo.City nocheck constraint FK_CountryID;
und Sie fügen ein neues Land hinzu
insert into dbo.Country(CountryID, Name) values(5, 'Iceland');
Sie würden mit diesem nicht so schönen Bild enden.
Der untere Zweig dient zum Aktualisieren der indizierten Ansicht. Es wird ein vollständiger Tabellenscan durchgeführt, um City
herauszufinden, ob das Land mit CountryID = 5
bereits Zeilen in der Tabelle enthält City
.
Wenn der Schlüssel vertrauenswürdig ist, weiß SQL Server, dass es keine Zeilen geben kann City
, die mit der neuen Zeile in übereinstimmen Country
.
INSERT
eine neue Zeile zu erstellen, die sich auf eine nicht vorhandene übergeordnete Zeile bezieht, oder wenn Sie später versuchen,DELETE
eine Zeile mit untergeordneten Zeilen zu erstellen?