Như bạn đã khám phá với exists
ví dụ của mình , SQL Server có thể sử dụng thực tế là khóa ngoại được tin cậy khi kế hoạch truy vấn được xây dựng.
Có điều gì khác tôi mất bằng cách sử dụng NOCHECK không?
Ngoài việc bạn có thể thêm các giá trị vào một cột không có ở đó như được trả lời bởi Ste Bov, bạn sẽ có nhiều kịch bản hơn trong đó kế hoạch truy vấn sẽ tốt hơn khi khóa ngoại được tin cậy.
Đây là một ví dụ với chế độ xem được lập chỉ mục .
Bạn có hai bảng với ràng buộc FK đáng tin cậy.
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);
Không có nhiều quốc gia nhưng có rất nhiều thành phố và một số trong số đó là những thành phố lớn.
Dữ liệu mẫu:
-- 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;
Các truy vấn được thực hiện thường xuyên nhất trong ứng dụng này có liên quan đến việc tìm kiếm số lượng thành phố lớn trên mỗi quốc gia. Để tăng tốc mọi thứ với điều đó, chúng tôi thêm một chế độ xem được lập chỉ mục.
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);
Sau một thời gian, nhu cầu thêm một quốc gia mới
insert into dbo.Country(CountryID, Name) values(4, 'Finland');
Kế hoạch truy vấn cho chèn đó không có gì ngạc nhiên.
Một chỉ mục cụm chèn vào Country
bảng.
Bây giờ, nếu khóa ngoại của bạn không được tin cậy
alter table dbo.City nocheck constraint FK_CountryID;
và bạn thêm một quốc gia mới
insert into dbo.Country(CountryID, Name) values(5, 'Iceland');
bạn sẽ kết thúc với hình ảnh không đẹp này.
Chi nhánh thấp hơn ở đó để cập nhật chế độ xem được lập chỉ mục. Nó thực hiện quét toàn bộ bảng City
để tìm hiểu xem quốc gia CountryID = 5
đã có hàng trong bảng chưa City
.
Khi khóa được tin cậy, SQL Server biết rằng không thể có hàng City
nào khớp với hàng mới trong Country
.
INSERT
một hàng mới liên quan đến một hàng cha mẹ không tồn tại hoặc nếu bạn cố gắngDELETE
một hàng có các hàng con sau này không?