Cột nào nên được lập chỉ mục trong MySQL?
Trong thời gian làm việc của mình, tôi có cơ hội làm việc với cơ sở dữ liệu MySQL có tới 700 triệu hàng. Bài đăng này sẽ nhấn mạnh cách lập chỉ mục và tối ưu hóa các truy vấn MySQL của bạn cho các chỉ mục Show
một năm trước • 11 phút đọc Mục lục Khi nào bạn nên tối ưu hóa cơ sở dữ liệu MySQL?Lý tưởng nhất là việc điều chỉnh hiệu suất truy vấn nên diễn ra thường xuyên. Các triệu chứng rõ ràng nhất của các vấn đề về hiệu suất là
Cách nhận biết các vấn đề về hiệu suất truy vấnNắm bắt truy vấn MySQL nào của bạn bị hỏng là điều cần thiết trong việc chẩn đoán vấn đề về hiệu suất. Hãy để tôi giới thiệu hai cách giúp bạn xác định các truy vấn gây ra tắc nghẽn hiệu suất
Sử dụng EXPLAIN để xác định mức độ cần thiết của chỉ mụcBây giờ bạn đã hiểu những kẻ gây rối trong ứng dụng là gì. Nhưng, làm thế nào bạn nhận ra rằng chúng hoạt động kém chỉ vì thiếu chỉ số? GIẢI THÍCH hoạt động với CHỌN, XÓA, THAY THẾ và CẬP NHẬT (Từ Mysql phiên bản 5. 7 trở đi) câu lệnh. Cũng giống như bạn, MySQL sẽ có các kế hoạch tuyệt vời cho từng truy vấn về cách thực hiện, chọn chỉ mục nào, cách tham gia các bảng và thứ tự cần duy trì để đạt hiệu suất tối ưu Kiểm tra mô tả bảng bên dưới, tôi muốn bạn ghi nhớ bảng này vì nó sẽ được sử dụng trong hầu hết các ví dụ của tôi. Hiện tại bảng không có bất kỳ chỉ mục nào Hãy lấy một truy vấn mẫu và phân tích những gì EXPLAIN mang lại cho truy vấn đó
Giải thích truy vấn trên đưa ra như… Hãy chia nhỏ kết quả EXPLAIN. Như bạn có thể thấy MySQL đã duyệt qua 152685 hàng (Xem cột. rows) của bảng để tìm một hàng phù hợp và nó tương đương với việc quét toàn bộ bảng vì bảng có tổng cộng 153728 hàng. Kết quả EXPLAIN có hai cột có tên là 9 và 0. Cột 9 cho chúng tôi biết các chỉ mục có sẵn trong một bảng hoặc các chỉ mục có thể được sử dụng cho các truy vấn của chúng tôi là gìCột 0 cho chúng tôi biết các chỉ mục mà MySQL đã sử dụng cho truy vấn được phân tích là gì. Hiện tại, cả hai đều trống. Cột 0 trống cung cấp cho bạn thông tin rằng truy vấn thiếu chỉ mụcHãy thêm một chỉ mục và kiểm tra điều gì sẽ xảy ra
Bây giờ bạn có thể thấy rằng truy vấn được tối ưu hóa tốt hơn và MySQL có thể tìm thấy kết quả phù hợp mà không cần duyệt qua nhiều hàng. Nếu bạn để ý, chúng tôi có tên chỉ mục của chúng tôi ở cả hai cột 9 và 0Tối ưu hóa các truy vấn phức tạpTôi biết rằng tối ưu hóa truy vấn bây giờ là một miếng bánh dành cho bạn. Trước khi chuyển sang các truy vấn phức tạp hơn, tôi muốn bạn tìm hiểu Quy tắc ngón tay cái trong việc lập chỉ mục MySQL chỉ có thể sử dụng một chỉ mục cho mỗi bảng trong một truy vấn (Có trường hợp ngoại lệ. ví dụ: Hợp nhất các chỉ mục). Lý tưởng nhất là điều này có nghĩa là một bảng trong truy vấn phải sử dụng một chỉ mục duy nhất cho tất cả mệnh đề where, nối bảng, nhóm theo và sắp xếp theo thứ tự Tin tôi đi, học quy tắc này là một bước đột phá trong sự nghiệp của tôi. Tôi đã từng tin rằng, cần phải thêm một chỉ mục riêng lẻ trên mỗi cột được sử dụng trong mệnh đề WHERE, mệnh đề THAM GIA, theo nhóm và theo thứ tự Hãy thực hiện một truy vấn khác
Hãy ghi nhớ quy tắc ngón tay cái, bạn đã biết rằng việc tạo hai chỉ mục trên email và danh mục sẽ không giúp ích gì 6Bây giờ, bạn sẽ làm gì?. Một chỉ mục nhiều cột (tổng hợp) để giải cứu Chỉ số tổng hợp là gì?Để tối ưu hóa các truy vấn như vậy, bạn nên tạo chỉ mục tổng hợp hoặc chỉ mục tổng hợp. Một chỉ mục tổng hợp có thể được mô tả như một hợp chất của nhiều cột. Hãy xem cách bạn có thể tạo chỉ mục tổng hợp 2Thứ tự cột có quan trọng đối với chỉ mục tổng hợp không?Vâng, nó quan trọng. Một cột có giá trị cardinality ít nhất (Có ít giá trị phân biệt hơn) phải luôn được định vị ở phía ngoài cùng bên trái trong chỉ mục tổng hợp. Thứ tự ưu tiên của các cột khác cũng phụ thuộc vào số lượng của các cột tương ứng Bây giờ, Làm cách nào để tìm số lượng bản số hoặc số lượng giá trị riêng biệt của một cột?. Bạn chỉ có thể thực hiện một truy vấn đếm đặc biệt trên cột. (Không nên thực hiện các truy vấn như vậy được đề cập bên dưới trong một DB sản xuất khi nó đang chạy trong thời gian cao điểm của lưu lượng truy cập. ) 3 4Ở đây bạn có thể thấy rằng số lượng của cột 7 nhỏ hơn số lượng của cột email, vì vậy chúng ta nên tạo một chỉ mục tổng hợp như sau 6Khi bạn quan sát thứ tự mà các cột này được lập chỉ mục và do đó, cách chúng được sắp xếp sẽ hạn chế việc sử dụng chỉ mục của chúng tôi đối với một số truy vấn cụ thể Ví dụ: chỉ mục chúng tôi vừa tạo 8 sẽ không có lợi cho truy vấn chẳng hạn như 8Khi nào thì một Chỉ mục Tổng hợp KHÔNG Hữu ích?Vâng, có một lý do cho nó Nếu bảng có chỉ mục nhiều cột, bất kỳ tiền tố ngoài cùng bên trái nào của chỉ mục đều có thể được trình tối ưu hóa sử dụng để tra cứu hàng. Ví dụ: nếu bạn có một chỉ mục ba cột trên 9, thì bạn đã lập chỉ mục các khả năng tìm kiếm trên 20, 21 và 9Điều này có nghĩa là trình tối ưu hóa MySQL không thể sử dụng chỉ mục để thực hiện tra cứu nếu truy vấn không chứa cột tiền tố ngoài cùng bên trái của chỉ mục. Vì vậy, cột ngoài cùng bên trái trong chỉ mục tổng hợp được gọi là cột Tra cứu MySQL có thể sử dụng 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 theo đúng 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 Trong truy vấn trên, tôi đã sử dụng email làm thuật ngữ mệnh đề WHERE duy nhất, do đó chỉ mục tổng hợp sẽ không hữu ích vì nó thiếu cột tra cứu của chỉ mục Có một lợi thế khác cho chỉ số tổng hợp; 27Ví dụ: hãy lấy một chỉ số 28. Chỉ mục này sẽ hữu ích trong các truy vấn bên dưới 9Nhưng không phải trong các truy vấn dưới đây 0Lập chỉ mục cho các truy vấn với toán tử OR và AND 1Trong trường hợp này, MySQL sẽ không thể sử dụng chỉ mục cho các truy vấn có điều kiện OR, ngay cả khi truy vấn chứa cột tra cứu và duy trì thứ tự của mệnh đề WHERE giống như chỉ mục Do đó, bạn nên tránh các điều kiện OR như vậy và cân nhắc chia truy vấn thành hai phần, kết hợp với một 29 (hoặc tốt hơn nữa, 30, trong trường hợp bạn biết sẽ không có bất kỳ kết quả trùng lặp nào) 2Lập chỉ mục cho các truy vấn với ORDER BY và GROUP BYhãy lấy cùng một chỉ mục 31 và chạy truy vấn 3Thao tác này sẽ sử dụng chỉ mục tổng hợp cho mệnh đề WHERE và nếu bạn cho rằng điều này sẽ thu hẹp các bản ghi có trạng thái có giá trị là 1, đáng tiếc là bây giờ bạn cần thực hiện sắp xếp các bản ghi kết quả này để sắp xếp chúng theo 7. Điều này là do chỉ mục không sắp xếp kết quả theo 7 theo bất kỳ cách có ý nghĩa nào và mệnh đề ORDER BY thiếu cột tra cứuĐiều này được gọi là Sắp xếp tệp (một số bạn có thể nhận thấy điều này trong kết quả giải thích). Điều này xảy ra vì chỉ mục mà chúng tôi đã tạo không đáp ứng được mệnh đề ORDER BY Sắp xếp tệp. Một sắp xếp xảy ra sau truy vấn; . Điều này sẽ không cần thiết nếu dữ liệu đã được sắp xếp theo chỉ mục theo cách bạn muốn Điều này cũng áp dụng ngay cả khi bạn chỉ muốn đọc 10 hàng 4Bạn vẫn sẽ tìm nạp hàng nghìn bản ghi, sắp xếp chúng và chỉ sau đó, trả lại 5 bản ghi hàng đầu trong khi loại bỏ phần còn lại của các bản ghi mà bạn đã dành thời gian xử lý 5Truy vấn này có thể tận dụng việc sử dụng chỉ mục được đề cập vì nó đủ điều kiện cho cả mệnh đề WHERE và mệnh đề ORDER BY Xem xét một truy vấn khác sắp xếp các hàng theo trạng thái theo thứ tự tăng dần và sau đó theo 7 theo thứ tự giảm dần 6MySQL không thể sử dụng các chỉ mục khi sắp xếp theo thứ tự hỗn hợp (cả ASC và DESC trong cùng mệnh đề ORDER BY) Ghi chú. Điều này đã thay đổi với việc phát hành chức năng đảo ngược chỉ mục và MySQL 8. x Bất cứ điều gì bạn thấy đối với ORDER BY cũng có thể áp dụng cho các câu lệnh GROUP BY. nếu bạn chạy truy vấn sau với chỉ mục tổng hợp trên 31 7Các bản ghi đã được sắp xếp theo 36, 7 và 38. Điều này cho phép bạn nhanh chóng lọc tất cả các bản ghi với 39. Sau khi các kết quả này được trả về, chúng cũng được sắp xếp dựa trên 7 do chỉ mục sắp xếp thứ tự các hàng khác với yêu cầu trong truy vấnCòn các Truy vấn có điều kiện THAM GIA hoặc PHẠM VI thì sao?Bạn nên có các chỉ mục trên tất cả các cột được sử dụng trong mệnh đề THAM GIA. tôi. e, các cột ở mỗi bên của mệnh đề ON của phép nối phải được lập chỉ mục Truy vấn được coi là truy vấn Phạm vi nếu nó sử dụng bất kỳ hoặc kết hợp các toán tử sau. Toán tử 41 , 42, 43, 44 hoặc 45, 46, 47, 48, 49, 60, 61 hoặc 62, phép so sánh LIKE (Nếu đối số của LIKE là một chuỗi hằng số không bắt đầu bằng ký tự đại diện. )Nếu bạn đang sử dụng một chỉ mục cho các truy vấn phạm vi, hãy cố gắng đảm bảo rằng cột mà bạn đang chỉ định toán tử phạm vi được sắp xếp cuối cùng trong chỉ mục. Bạn chỉ nên thêm một trong số chúng cho mỗi bảng — điều kiện chọn lọc nhất, vì MySQL chỉ có thể xử lý một 'cột có khoảng cách' trong mỗi chỉ mục Tôi nên lập chỉ mục những cột nào?Bạn nên nhận ra từ tất cả những gì chúng ta đã thảo luận rằng nó phụ thuộc vào
Bạn cũng có thể tham khảo hướng dẫn lập chỉ mục và thiết kế lược đồ MySQL này Thưởng. Bao gồm các chỉ sốTrước khi hiểu chỉ mục bao gồm là gì, hãy tìm hiểu cách MySQL tìm nạp các hàng phù hợp cho một truy vấn 63Nếu bạn có MySQL với công cụ InnoDB, bạn sẽ thường sử dụng các chỉ mục như Chỉ mục cụm và chỉ mục phụ Khi bạn xác định KHÓA CHÍNH trên bảng của mình, InnoDB sẽ sử dụng nó làm chỉ mục nhóm. Lưu trữ bảng InnoDB được tổ chức dựa trên giá trị của các cột khóa chính, để tăng tốc các truy vấn và sắp xếp liên quan đến các cột khóa chính. Tất cả các chỉ mục khác với chỉ mục nhóm được gọi là chỉ mục phụ Bây giờ, điểm chính ở đây là trong InnoDB, mỗi bản ghi trong chỉ mục phụ chứa các cột khóa chính cho hàng, cũng như các cột được chỉ định cho chỉ mục phụ. InnoDB sử dụng giá trị khóa chính này để tìm kiếm hàng trong chỉ mục được nhóm Vì vậy, MySQL phải phụ thuộc vào chỉ mục Khóa chính để thực hiện giai đoạn tìm nạp ngay cả khi tất cả các hàng phù hợp được xác định bằng chỉ mục (Chỉ mục phụ) 8Xem xét truy vấn trên và giả sử bạn đã tạo một chỉ mục trên 64MySQL có thể dễ dàng truy xuất các giá trị Khóa chính cho tất cả các bản ghi có giá trị chế độ là 2, tuy nhiên, để tìm nạp cột di động, MySQL vẫn cần sử dụng các giá trị khóa chính để tìm nạp dữ liệu hàng từ chỉ mục Khóa chính Bây giờ, nếu chúng ta thêm một chỉ mục như thế này thì sao? 9Sử dụng chỉ mục trên, MySQL có thể dễ dàng truy xuất các giá trị Khóa chính cho tất cả các bản ghi có giá trị 64 là 2 và để tìm nạp cột di động, MySQL không cần phụ thuộc vào chỉ mục Khóa chính để tìm nạp dữ liệu hàng. Truy vấn trên được bao phủ hoàn toàn bởi chỉ mục và do đó được gọi là chỉ mục bao phủThiết kế cơ sở dữ liệu lý tưởng sử dụng chỉ mục bao phủ khi thực tế; Các phương pháp hay nhất để lập chỉ mục cơ sở dữ liệu MySQL
0Nếu bạn sử dụng một hàm ở phía bên trái của toán tử thì MySQL sẽ không sử dụng chỉ mục ngay cả khi cột có chỉ mục trên đó. Nhưng, bạn có thể có một chức năng trong tay phải, chẳng hạn như Những cột nào nên được lập chỉ mục SQL?Các cột có một hoặc nhiều đặc điểm sau đây là những ứng cử viên tốt để lập chỉ mục. Các giá trị trong cột là duy nhất hoặc có một vài giá trị trùng lặp . Có nhiều loại giá trị (tốt cho các chỉ mục thông thường). Có một phạm vi giá trị nhỏ (tốt cho các chỉ mục bitmap).
Những cột nào tốt cho việc lập chỉ mục?Các cột có một hoặc nhiều đặc điểm sau đây là những ứng cử viên tốt để lập chỉ mục. . Các giá trị là duy nhất trong cột hoặc có một vài giá trị trùng lặp Có nhiều loại giá trị (tốt cho các chỉ mục thông thường) Có một phạm vi giá trị nhỏ (tốt cho các chỉ mục bitmap) Tôi có nên lập chỉ mục tất cả các cột MySQL không?Lập chỉ mục tất cả các cột không chính xác . Nó ảnh hưởng đến hiệu suất của các hoạt động ghi. Mỗi chỉ mục bổ sung cần thêm thời gian để cập nhật sau thao tác ghi. |