Có một khóa ngoại tự động tạo ra một chỉ mục?


389

Tôi đã được thông báo rằng nếu tôi nhập khóa ngoài hai bảng, SQL Server sẽ tạo ra thứ gì đó giống với một chỉ mục trong bảng con. Tôi có một thời gian khó tin rằng điều này là đúng, nhưng không thể tìm thấy nhiều điều liên quan cụ thể đến vấn đề này.

Lý do thực sự của tôi để hỏi điều này là bởi vì chúng tôi đang trải qua thời gian phản hồi rất chậm trong một tuyên bố xóa đối với một bảng có thể có 15 bảng liên quan. Tôi đã hỏi anh chàng cơ sở dữ liệu của chúng tôi và anh ta nói rằng nếu có một khóa ngoại trên các trường, thì nó hoạt động như một chỉ mục. Kinh nghiệm của bạn với điều này là gì? Tôi có nên thêm chỉ mục trên tất cả các trường khóa ngoại hay chúng chỉ là chi phí không cần thiết?


Tôi có cùng sự hiểu biết với anh chàng DB của bạn - rằng FK thực tế tạo ra một chỉ mục.
Vinnie

9
Không - FK KHÔNG tự động tạo chỉ mục. Nó có ý nghĩa để tạo một cái - nhưng nó không được thực hiện tự động bởi SQL Server.
marc_s

47
không ngớ ngẩn để hỏi điều này cả!
marc_s

5
Nếu bạn đang xóa chậm và bảng bạn đang xóa khỏi các bảng khác được tham chiếu, có thể bạn sẽ tăng hiệu suất bằng cách lập chỉ mục các khóa ngoại trong các bảng khác . Điều này là do khi SQL đang xóa một hàng, nó cần kiểm tra tính toàn vẹn tham chiếu trên hàng. Để làm điều này, rõ ràng cần phải kiểm tra xem không có hàng nào khác tồn tại tham chiếu đến hàng bạn đang xóa.
Noel Kennedy

3
Tôi muốn nói rằng một anh chàng cơ sở dữ liệu không biết điều này cần phải được đào tạo nghiêm túc. Cơ sở dữ liệu người chịu trách nhiệm về hiệu suất, công việc của họ là phải biết loại điều này. Điều này cho thấy sự bất tài thô thiển.
HLGEM

Câu trả lời:


343

Khóa ngoại là một ràng buộc, mối quan hệ giữa hai bảng - không liên quan gì đến chỉ số mỗi se.

Nhưng có một thực tế được biết là rất có ý nghĩa khi lập chỉ mục tất cả các cột là một phần của bất kỳ mối quan hệ khóa ngoài nào, bởi vì thông qua mối quan hệ FK, bạn thường sẽ cần tra cứu một bảng liên quan và trích xuất một số hàng nhất định dựa trên một giá trị duy nhất hoặc một phạm vi các giá trị.

Vì vậy, sẽ hợp lý khi lập chỉ mục cho bất kỳ cột nào liên quan đến FK, nhưng FK mỗi se không phải là một chỉ mục.

Kiểm tra bài viết xuất sắc của Kimberly Tripp "Khi nào SQL Server ngừng đặt chỉ mục trên các cột Khóa ngoài?" .


Vâng. Tôi chỉ tích cực rằng PostgreSQL tạo ra một chỉ mục. Tôi khá chắc chắn rằng MySQL có. Làm cho chỉ số có ý nghĩa, nhưng KHÔNG BẮT BUỘC. Rốt cuộc, tại sao lại tham khảo một cái gì đó nếu mỗi lần DB đi tìm nó thì nó phải thực hiện quét bảng?
MBCook

Bài viết này được đề cập ở trên là khó hiểu vì máy chủ SQL hoặc bất kỳ cơ sở dữ liệu nào khác không bao giờ đặt chỉ mục trên FK.
vsingh

7
@vsingh: đó chính xác là những gì bài viết cố gắng truyền đạt - đó là một quan niệm sai lầm phổ biến rằng FK tự động tạo ra một chỉ mục - nó không làm điều đó.
marc_s

5
@MBCook Không, PostgreSQL không (ít nhất là trong 9.2 hoặc bất kỳ phiên bản trước nào) tự động tạo một chỉ mục ở phía tham chiếu của mối quan hệ khóa ngoài được xác định REFERENCES. Nó tự động tạo một UNIQUEchỉ mục cho một PRIMARY KEYhoặc một UNIQUEràng buộc và yêu cầu phải có một UNIQUEchỉ mục cho phần cuối được tham chiếu của mối quan hệ khóa ngoài, nhưng không có gì tự động cho phần kết thúc tham chiếu , mặc dù đó thường là một ý tưởng tốt để tự tạo một. Xem stackoverflow.com/questions/970562/iêu
Craig Ringer

16
Sự nhầm lẫn có thể tồn tại bởi vì MySQL InnoDB đều yêu cầu và tự động tạo một chỉ mục khi bạn thêm khóa ngoại - dev.mysql.com/doc/refman/5.5/en/ Lỗi
humbads

42

Wow, câu trả lời là tất cả trên bản đồ. Vì vậy, Tài liệu nói:

Ràng buộc FOREIGN KEY là một ứng cử viên cho một chỉ mục bởi vì:

  • Các thay đổi đối với các ràng buộc CHÍNH CHÍNH được kiểm tra với các ràng buộc FOREIGN KEY trong các bảng liên quan.

  • Các cột khóa ngoài thường được sử dụng trong các tiêu chí nối khi dữ liệu từ các bảng có liên quan được kết hợp trong các truy vấn bằng cách khớp (các) cột trong ràng buộc FOREIGN KEY của một bảng với (các) cột khóa chính hoặc duy nhất trong bảng khác. Một chỉ mục cho phép Microsoft® SQL Server ™ 2000 nhanh chóng tìm thấy dữ liệu liên quan trong bảng khóa ngoại. Tuy nhiên, tạo ra chỉ số này không phải là một yêu cầu. Dữ liệu từ hai bảng có liên quan có thể được kết hợp ngay cả khi không xác định ràng buộc PRIMARY KEY hoặc FOREIGN KEY giữa các bảng, nhưng mối quan hệ khóa ngoài giữa hai bảng cho biết hai bảng đã được tối ưu hóa để được kết hợp trong truy vấn sử dụng các khóa như tiêu chí của nó.

Vì vậy, có vẻ như khá rõ ràng (mặc dù tài liệu hơi sai sót) rằng trên thực tế nó không tạo ra một chỉ mục.


5
Chính xác - đó là một CANDIDATE cho một chỉ mục - nhưng nó không tự động được tạo như một! Thực sự khá rõ ràng, IMHO :-)
marc_s

4
Tôi thấy phần này bị nhầm lẫn: "mối quan hệ khóa ngoài giữa hai bảng biểu thị rằng hai bảng đã được tối ưu hóa để được kết hợp trong một truy vấn sử dụng các khóa làm tiêu chí của nó." Điều đó nên đọc "... hai bảng nên được tối ưu hóa ..."
Yishai

18

Không, không có chỉ mục ngầm trên các trường khóa ngoại, nếu không thì tại sao Microsoft lại nói "Tạo chỉ mục trên khóa ngoại thường hữu ích" . Đồng nghiệp của bạn có thể gây nhầm lẫn lĩnh vực chính nước ngoài trong bảng giới thiệu với khóa chính trong gọi để bàn - khóa chính làm tạo ra một chỉ số tiềm ẩn.


"Một chỉ số ngầm" là gì? Có phải nó chỉ ngụ ý rằng có ab * cây mà không tạo ra nó?
Stephanie Trang

1
Trang @Stephanie: Đó là một biểu thức tôi vừa tạo ra cho câu trả lời này có nghĩa là một chỉ mục được tạo tự động. Nếu bạn khai báo khóa chính, máy chủ SQL sẽ tự động tạo và lập chỉ mục cho nó. Nhưng không phải là bạn khai báo khóa ngoại (một số hệ thống DB khác làm).
Michael Borgwardt

7

SQL Server tự động tạo các chỉ mục cho Khóa chính, nhưng không cho Khóa ngoài. Tạo chỉ mục cho Khóa ngoại. Nó có thể có giá trị trên đầu.


6

Giả sử bạn có một bảng lớn gọi là đơn đặt hàng và một bảng nhỏ gọi là khách hàng. Có một khóa ngoại từ một đơn đặt hàng cho một khách hàng. Bây giờ nếu bạn xóa một khách hàng, Sql Server phải kiểm tra xem không có đơn hàng mồ côi nào; nếu có, nó sẽ phát sinh lỗi.

Để kiểm tra xem có đơn hàng nào không, Sql Server phải tìm kiếm bảng đơn hàng lớn. Bây giờ nếu có một chỉ mục, việc tìm kiếm sẽ nhanh chóng; nếu không có, việc tìm kiếm sẽ chậm.

Vì vậy, trong trường hợp này, việc xóa chậm có thể được giải thích do không có chỉ mục. Đặc biệt là nếu Sql Server sẽ phải tìm kiếm 15 bảng lớn mà không có chỉ mục.

PS Nếu khóa ngoại đã BẬT XÓA CASCADE, Sql Server vẫn phải tìm kiếm bảng đơn hàng, nhưng sau đó để xóa bất kỳ đơn hàng nào tham chiếu đến khách hàng đã xóa.


Chính xác - đó là lý do một chỉ số trên FK thực sự có ý nghĩa (hầu hết thời gian)
marc_s

1
Hầu hết thời gian? Có vẻ đây là trường hợp xóa từ cha mẹ. Nếu hầu hết thời gian bạn xóa khỏi cha mẹ, tôi đoán đó là sự thật.
Stephanie Trang

6

Khóa ngoại không tạo chỉ mục. Chỉ các ràng buộc khóa thay thế (UNIQUE) và các ràng buộc khóa chính mới tạo ra các chỉ mục. Điều này đúng trong Oracle và SQL Server.


3

Không phải kiến ​​thức của tôi. Khóa ngoại chỉ thêm một ràng buộc rằng giá trị trong khóa con cũng được biểu thị ở đâu đó trong cột cha. Nó không nói với cơ sở dữ liệu rằng khóa con cũng cần được lập chỉ mục, chỉ bị ràng buộc.


3

Nói đúng ra, khóa ngoại hoàn toàn không liên quan gì đến chỉ mục, vâng. Nhưng, như các diễn giả ở trên tôi đã chỉ ra, thật hợp lý khi tạo một cái để tăng tốc độ tìm kiếm FK. Thực tế, trong MySQL, nếu bạn không chỉ định một chỉ mục trong khai báo FK của mình, công cụ (InnoDB) sẽ tự động tạo nó cho bạn.


3

Trong PostgeSql, bạn có thể tự kiểm tra các chỉ mục nếu bạn nhấn \ d tablename

Bạn sẽ thấy các chỉ mục btree đã được tạo tự động trên các cột với khóa chính và các ràng buộc duy nhất, nhưng không phải trên các cột có khóa ngoại.

Tôi nghĩ rằng câu trả lời cho câu hỏi của bạn ít nhất là cho postgres.


Xin lỗi, tôi không nhận thấy rằng câu hỏi liên quan đến MS SQL Server nhưng sau khi đăng câu trả lời. Nó có lẽ vẫn có thể giúp ai đó ...
Gregor

2

Tôi nhận thấy rằng Entity Framework 6.1 chỉ vào MSSQL sẽ tự động thêm các chỉ mục trên các khóa ngoại.


Tôi không tin điều đó nếu bạn gắn cờ cột theo cách thủ công như một phần của chỉ mục (ví dụ: nếu bạn đang tạo chỉ mục tổng hợp cho nhiều thành viên)
Rowland Shaw

0

InnoDB yêu cầu lập chỉ mục trên khóa ngoạikhóa được tham chiếu để kiểm tra khóa ngoại có thể nhanh và không yêu cầu quét bảng. Trong bảng tham chiếu, phải có một chỉ mục trong đó các cột khóa ngoại được liệt kê là các cột đầu tiên theo cùng một thứ tự.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.