Jak odkryłeś na exists
przykładzie, SQL Server może wykorzystać fakt, że klucz obcy jest zaufany podczas budowania planu zapytań.
Czy mogę coś jeszcze stracić, używając NOCHECK?
Oprócz tego, że możesz dodać wartości do kolumny, których nie powinno tam być, na co odpowiada Ste Bov , będziesz miał więcej scenariuszy, w których plan zapytań będzie lepszy, gdy zaufany klucz obcy.
Oto jeden przykład z widokiem indeksowanym .
Masz dwie tabele z zaufanym ograniczeniem FK.
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);
Nie ma tak wielu krajów, ale gazillion miast, a niektóre z nich to duże miasta.
Przykładowe dane:
-- 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;
Najczęściej wykonywane zapytania w tej aplikacji dotyczą znalezienia liczby dużych miast na kraj. Aby to przyspieszyć, dodajemy widok indeksowany.
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);
Po chwili pojawia się potrzeba dodania nowego kraju
insert into dbo.Country(CountryID, Name) values(4, 'Finland');
Plan zapytań dla tej wstawki nie ma niespodzianek.
Klastrowany indeks wstawia do Country
tabeli.
Teraz, jeśli twój klucz obcy nie był zaufany
alter table dbo.City nocheck constraint FK_CountryID;
i dodajesz nowy kraj
insert into dbo.Country(CountryID, Name) values(5, 'Iceland');
skończyłbyś z tym niezbyt ładnym obrazem.
Dolna gałąź służy do aktualizacji widoku indeksowanego. Wykonuje pełny skan tabeli, City
aby dowiedzieć się, czy kraj, w którym są CountryID = 5
już wiersze w tabeli City
.
Gdy klucz jest zaufany, SQL Server wie, że nie może być żadnych wierszy City
, które pasowałyby do nowego wiersza Country
.
INSERT
nowego wiersza, który odnosi się do nieistniejącego wiersza nadrzędnego lub jeśli spróbujeszDELETE
wiersza, który ma wiersze podrzędne później?