Có phải MySQL chỉ mục các cột khóa ngoại tự động?


Câu trả lời:


229

Có, nhưng chỉ trên . Innodb hiện là định dạng bảng vận chuyển duy nhất có khóa ngoại được triển khai.


1
Bạn có bất kỳ lý do nào để tin rằng MySQL sẽ cho phép các khóa ngoại trên các cột không được lập chỉ mục cho bất kỳ loại bảng nào khác không?
Robert Gamble

Tôi thực sự không thể trả lời điều đó. Bạn có thể muốn tìm kiếm các công cụ lưu trữ Maria và Falcon sẽ được phát hành trong MySQL 6.0 và xem liệu chúng có hỗ trợ khóa ngoại trên các cột không được lập chỉ mục không.
Cấp Limberg

Rõ ràng điều này không đúng. Tôi có một bảng lớn (1 triệu bản ghi) và đếm (*) trong đó fkey =? sẽ mất 15 giây. Đã thêm một chỉ mục trên cột fkey và mọi thứ sẽ diễn ra trong một giây.
AbiusX

Cùng một thí nghiệm với một bảng khác và 10 triệu hồ sơ. Đây là của MySQL 5.1 InnoDB. Bảng có ba trường, một trường là số nguyên khóa chính, trường kia đã được lập chỉ mục. Cái thứ ba là khóa ngoại đối với khóa chính của bảng khác. Không thêm chỉ mục rõ ràng, việc tra cứu mất vài giây ở đây. Hiển thị chỉ mục từ bảng cũng không hiển thị một chỉ mục trên đó.
AbiusX

@AbiusX 5.1 có lẽ đã quá cũ, hãy xem câu trả lời của MrAlexander dưới đây.
e2-e4

131

Rõ ràng một chỉ mục được tạo tự động như được chỉ định trong liên kết robert đã đăng .

InnoDB yêu cầu lập chỉ mục trên khóa ngoại và khóa 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ự. Một chỉ mục như vậy được tạo tự động trên bảng tham chiếu nếu nó không tồn tại. (Điều này trái ngược với một số phiên bản cũ hơn, trong đó các chỉ mục phải được tạo rõ ràng hoặc việc tạo các ràng buộc khóa ngoại sẽ thất bại.) Index_name, nếu được đưa ra, được sử dụng như mô tả trước đây.

Các ràng buộc của InnoDB và NGOẠI TỆ


9
+1 câu trả lời tốt hơn nhiều so với câu trả lời được chọn là cung cấp bằng chứng từ các tài liệu
Gaz_Edge

6
Văn bản được trích dẫn dường như không được bao gồm trong các tài liệu MySQL nữa, làm cho nó không rõ liệu điều này có còn đúng hay không.
Courtney Miles

7
@ user2045006 bạn có thể tham khảo doc 5.0 cũng như doc 5.6 cho văn bản được trích dẫn chính xác
sactiw 17/03/2015

1
Trong các tài liệu hiện tại, chỉ có một thay đổi nhỏ trong văn bản (tôi cho rằng ý nghĩa là tương tự):InnoDB permits a foreign key to reference any index column or group of columns. However, in the referenced table, there must be an index where the referenced columns are the first columns in the same order.
Lucas Basquerotto

20

4
Câu trả lời này là một ví dụ tuyệt vời về lý do tại sao một câu trả lời không bao giờ chỉ bao gồm một liên kết đến một câu trả lời có thể. Tại thời điểm này, trang được liên kết hoàn toàn không trả lời câu hỏi.
Mike

1
Vui lòng thêm tất cả thông tin vào câu trả lời thay vì chỉ đăng một liên kết
Nico Haase

11

Bạn không nhận được chỉ mục tự động nếu bạn thực hiện ALTER TABLE (thay vì CREATE TABLE), ít nhất là theo các tài liệu (liên kết dành cho 5.1 nhưng tương tự với 5.5):

[...] Khi bạn thêm một ràng buộc khóa ngoài vào bảng bằng ALTER TABLE, hãy nhớ tạo các chỉ mục cần thiết trước tiên.


2
Tôi cũng đã thử trên MySQL 5.6 và MariaDB 10 và ALTER TABLE tạo ra một chỉ mục. Thật thú vị khi mysqlindexcheck báo cáo chỉ số đó là "chỉ mục dự phòng". Tôi đã cố gắng thả nó nhưng tôi đã gặp lỗi sau: "ERROR 1553 (HY000): Không thể thả chỉ mục 'index_name': cần thiết trong một ràng buộc khóa ngoài". Vì vậy, không thể bỏ chỉ số đó và giữ khóa ngoại.
Ciprian Stoica

Bạn có thể muốn xem lại câu trả lời của bạn. MySQL luôn tạo một chỉ mục để tăng tốc độ kiểm tra khóa ngoại nếu không tồn tại . Các tài liệu đang cố gắng nói với bạn rằng việc tạo các chỉ mục trước các ràng buộc khóa ngoài có thể tăng tốc mọi thứ lên một chút. Ví dụ: chỉ mục khóa tổng hợp có thể đóng vai trò là chỉ mục cho kiểm tra khóa ngoại có thể được InnoDB sử dụng thay vì tự động tạo chỉ mục dự phòng.
BMiner

7

Đối với những người đang tìm kiếm trích dẫn từ các 5.7 tài liệu :

MySQL yêu cầu các chỉ mục trên khóa ngoại và khóa 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ự. Một chỉ mục như vậy được tạo tự động trên bảng tham chiếu nếu nó không tồn tại. Chỉ mục này có thể được giảm âm thầm sau đó, nếu bạn tạo một chỉ mục khác có thể được sử dụng để thực thi ràng buộc khóa ngoại. index_name, nếu được cung cấp, được sử dụng như được mô tả trước đây.


4

Như đã nêu, nó làm cho InnoDB. Lúc đầu, tôi nghĩ thật lạ khi nhiều người khác (đặc biệt là MS SQL và DB2) không có. Quét không gian bảng chỉ tốt hơn quét chỉ mục khi có rất ít hàng trong bảng - vì vậy, trong phần lớn các trường hợp, khóa ngoại sẽ muốn được lập chỉ mục. Sau đó, nó đánh tôi - điều này không nhất thiết có nghĩa là nó phải là một chỉ số độc lập (một cột) - trong đó nó nằm trong Chỉ số FK tự động của MySQL. Vì vậy, có thể đó là lý do MS SQL, DB2 (Oracle tôi không chắc chắn), v.v. để lại cho DBA; sau khi tất cả nhiều chỉ mục trên các bảng lớn có thể gây ra vấn đề về hiệu suất và không gian.


Bạn đưa ra một điểm tốt về các chỉ số khóa tổng hợp; tuy nhiên, MySQL sẽ tự động / âm thầm loại bỏ chỉ mục khóa đơn được tạo tự động nếu chỉ mục khóa tổng hợp mới được tạo hoàn thành nghĩa vụ làm cho khóa ngoại kiểm tra nhanh. Thành thật mà nói, tôi không biết tại sao MS SQL, DB2 và những người khác không làm điều này. Họ có rất ít lý do. Tôi không thể nghĩ về trường hợp sử dụng trong đó chỉ mục được tạo tự động trên khóa ngoại sẽ có hại.
BMiner

2

Vâng, Innodbcung cấp điều này. Bạn có thể đặt một tên khóa ngoại sau FOREIGN KEYmệnh đề hoặc để nó để cho MySQL tạo tên cho bạn. MySQL tự động tạo một chỉ mục với foreign_key_nametên.

CONSTRAINT constraint_name
FOREIGN KEY foreign_key_name (columns)
REFERENCES parent_table(columns)
ON DELETE action
ON UPDATE action

0

Có, Mysql lập chỉ mục khóa ngoại tự động khi bạn tạo bảng có khóa ngoại với bảng khác.


-2

Không thể lấy khóa chỉ mục tự động sử dụng

ALTER TABLE (NAME OF THE TABLE) ADD INDEX (FOREIGN KEY)

Tên của bảng mà bạn đã tạo ví dụ như ảnh và FOREIGN KEY chẳng hạn photograph_id. Mã phải như thế này

ALTER TABLE photographs ADD INDEX (photograph_id);
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.