Hai chỉ mục một cột so với một chỉ mục hai cột trong MySQL?


113

Tôi phải đối mặt với những điều sau đây và tôi không chắc đâu là phương pháp hay nhất.

Hãy xem xét bảng sau (sẽ lớn hơn):

id PK | giver_id FK | người nhận_id FK | ngày

Tôi đang sử dụng InnoDB và từ những gì tôi hiểu, nó tự động tạo các chỉ mục cho hai cột khóa ngoại. Tuy nhiên, tôi cũng sẽ thực hiện rất nhiều truy vấn mà tôi cần kết hợp một tổ hợp cụ thể của:

SELECT...WHERE giver_id = x AND recipient_id = t.

Mỗi sự kết hợp như vậy sẽ là duy nhất trong bảng.

Có lợi ích gì khi thêm một chỉ mục hai cột trên các cột này không, hay hai chỉ mục riêng lẻ về lý thuyết là đủ / giống nhau?


1
Nếu sự kết hợp của hai cột là duy nhất, bạn có thể tạo chỉ mục hai cột với tính năng duy nhất sẽ không chỉ tăng tốc độ truy vấn của bạn mà còn thêm tính nhất quán cho bảng của bạn.
sguven

"MySQL có thể sử dụng các chỉ mục nhiều cột cho các truy vấn kiểm tra tất cả các cột trong chỉ mục hoặc các truy vấn chỉ kiểm tra cột đầu tiên, hai cột đầu tiên, ba cột đầu tiên, v.v. Nếu bạn chỉ định các cột ở bên phải theo thứ tự trong định nghĩa chỉ mục, một chỉ mục tổng hợp duy nhất có thể tăng tốc một số loại truy vấn trên cùng một bảng. " - Chỉ mục nhiều cột
AlikElzin-kilaka

Để ngoại suy trên @ user1585784; Nếu sự kết hợp của hai cột là duy nhất, tôi nghĩ người ta nên sử dụng một khóa duy nhất cho chúng. Trong thực tế, nếu ai muốn thực thi sự độc đáo vào mức độ cơ sở dữ liệu, một chìa khóa duy nhất là cách dễ nhất để đi ...
Erk

Câu trả lời:


132

Nếu bạn có hai chỉ mục cột đơn, chỉ một trong số chúng sẽ được sử dụng trong ví dụ của bạn.

Nếu bạn có một chỉ mục với hai cột, truy vấn có thể nhanh hơn (bạn nên đo lường). Chỉ mục hai cột cũng có thể được sử dụng làm chỉ mục cột duy nhất, nhưng chỉ cho cột được liệt kê đầu tiên.

Đôi khi có thể hữu ích khi có một chỉ mục trên (A, B) và một chỉ mục khác trên (B). Điều này làm cho các truy vấn sử dụng một hoặc cả hai cột nhanh hơn, nhưng tất nhiên cũng sử dụng nhiều không gian đĩa hơn.

Khi chọn các chỉ mục, bạn cũng cần xem xét ảnh hưởng của việc chèn, xóa và cập nhật. Nhiều chỉ mục hơn = cập nhật chậm hơn.


1
"MySQL có thể sử dụng các chỉ mục nhiều cột cho các truy vấn kiểm tra tất cả các cột trong chỉ mục hoặc các truy vấn chỉ kiểm tra cột đầu tiên, hai cột đầu tiên, ba cột đầu tiên, v.v. Nếu bạn chỉ định các cột ở bên phải theo thứ tự trong định nghĩa chỉ mục, một chỉ mục tổng hợp duy nhất có thể tăng tốc một số loại truy vấn trên cùng một bảng. " - Chỉ mục nhiều cột
AlikElzin-kilaka

33

Một chỉ mục bao gồm:

ALTER TABLE your_table ADD INDEX (giver_id, recipient_id);

... có nghĩa là chỉ mục có thể được sử dụng nếu một truy vấn được tham chiếu đến giver_idhoặc kết hợp của giver_idrecipient_id. Lưu ý rằng tiêu chí chỉ mục được dựa ngoài cùng bên trái - một truy vấn chỉ đề cập đến recipient_idsẽ không thể sử dụng chỉ mục bao hàm trong câu lệnh tôi đã cung cấp.

Ngoài ra, MySQL chỉ có thể sử dụng một chỉ mục cho mỗi SELECT vì vậy một chỉ mục bao trùm sẽ là phương tiện tốt nhất để tối ưu hóa các truy vấn của bạn.


10
MySQL can only use one index per SELECTđiều này không còn đúng nữa, sẽ rất tuyệt nếu bạn chỉnh sửa câu trả lời của mình để được cập nhật.
Davor

Bạn có vui lòng giải thích tại sao chỉ mục bao phủ sẽ không thể được sử dụng bởi recipient_id?
Ivo Pereira

2
@IvoPereira Chỉ mục nhiều cột trong MySQL cho phép bạn sử dụng tất cả các trường trong chỉ mục từ trái sang phải. Ví dụ: nếu bạn có INDEX (col1, col2, col3, col4)thì chỉ mục sẽ được áp dụng cho các tìm kiếm có WHEREmệnh đề như col1 = 'A'hoặc col1 = 'A' AND col2 = 'B'hoặc col1 = 'A' AND col2 ='B' AND col3 = 'C' AND col4 = 'D', nhưng chỉ mục cụ thể này sẽ không được sử dụng cho bất kỳ điều gì như WHERE col2 = 'B'hoặc WHERE col3 = 'C' AND col4 = 'D'vì các trường tìm kiếm không được để lại nhiều nhất trong định nghĩa chỉ mục. Bạn sẽ phải thêm các chỉ mục bổ sung để bao gồm các trường đó.
Slicktrick

"một chỉ mục cho mỗi SELECT" , điều này có còn đúng với mariadb 10.1 không?
oldboy

1
@Anthony: Không. Hãy xem bình luận của Davor ở trên.
kapad

4

Nếu một trong các chỉ mục khóa ngoại đã rất chọn lọc, thì công cụ cơ sở dữ liệu nên sử dụng chỉ mục đó cho truy vấn bạn đã chỉ định. Hầu hết các công cụ cơ sở dữ liệu sử dụng một số loại heuristic để có thể chọn chỉ mục tối ưu trong tình huống đó. Nếu bản thân không chỉ mục nào có tính chọn lọc cao, thì việc thêm chỉ mục được xây dựng trên cả hai khóa có lẽ là rất hợp lý vì bạn nói rằng bạn sẽ sử dụng loại truy vấn đó rất nhiều.

Một điều khác cần xem xét là nếu bạn có thể loại bỏ trường PK trong bảng này và xác định chỉ mục khóa chính trên các trường giver_idrecipient_id. Bạn đã nói rằng sự kết hợp là duy nhất, vì vậy điều đó có thể hoạt động (với rất nhiều điều kiện khác mà chỉ bạn mới có thể trả lời). Tuy nhiên, thông thường, tôi nghĩ rằng sự phức tạp được thêm vào không đáng để gặp rắc rối.


Cảm ơn Mark, một trong những chìa khóa thực sự rất chọn lọc nên nó sẽ ổn. Tôi đã chọn giữ nguyên hai chỉ số (tự động) và xem nó hoạt động như thế nào theo thời gian. Tôi cũng đã nghĩ về khóa chính của người tặng kết hợp: người nhận, nhưng vì mỗi trường cũng cần được tìm kiếm riêng lẻ, nó sẽ chỉ thêm chi phí php. Ngoài ra, khóa mới sẽ là một chuỗi (dài hơn) thay vì một số nguyên (ngắn hơn).
Tom

2

Một điều khác cần xem xét là các đặc tính hiệu suất của cả hai cách tiếp cận sẽ dựa trên kích thước và số lượng của tập dữ liệu. Bạn có thể thấy rằng chỉ mục 2 cột chỉ trở nên hiệu quả hơn ở một ngưỡng kích thước tập dữ liệu nhất định hoặc hoàn toàn ngược lại. Không có gì có thể thay thế các chỉ số hiệu suất cho kịch bản chính xác của bạn.


bạn có thể vui lòng liên kết đến một số tài liệu về điều này. Cảm ơn.
kapad
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.