Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Làm cách nào để MySQL sử dụng INDEX cho truy vấn chế độ xem?

Làm cách nào để bạn có được MySQL để sử dụng một chỉ mục cho một truy vấn chế độ xem? Câu trả lời ngắn gọn, cung cấp một chỉ mục mà MySQL có thể sử dụng.

Trong trường hợp này, chỉ số tối ưu có thể là chỉ số "bao trùm":

... ON highscores (player, happened_in, score)

Có khả năng MySQL sẽ sử dụng chỉ mục đó và GIẢI THÍCH sẽ hiển thị:"Using index" do WHERE player = 24 (một vị từ bình đẳng trên cột đầu trong chỉ mục. GROUP BY happened_id (cột thứ hai trong chỉ mục), có thể cho phép MySQL tối ưu hóa điều đó bằng cách sử dụng chỉ mục để tránh thao tác sắp xếp. Bao gồm score trong chỉ mục sẽ cho phép truy vấn đáp ứng hoàn toàn từ chỉ mục mà không cần phải truy cập (tra cứu) các trang dữ liệu được chỉ mục tham chiếu.

Đó là câu trả lời nhanh chóng. Câu trả lời dài hơn là MySQL rất ít có khả năng sử dụng chỉ mục có cột đứng đầu là happened_id cho truy vấn chế độ xem.

Tại sao chế độ xem lại gây ra sự cố về hiệu suất

Một trong những vấn đề bạn gặp phải với chế độ xem MySQL là MySQL không "đẩy" vị từ từ truy vấn bên ngoài xuống truy vấn chế độ xem.

Truy vấn bên ngoài của bạn chỉ định WHERE happened_in = 2006 . Trình tối ưu hóa MySQL không xem xét vị từ khi nó chạy "truy vấn chế độ xem" bên trong. Truy vấn cho dạng xem đó được thực thi riêng biệt, trước truy vấn bên ngoài. Tập kết quả từ việc thực hiện truy vấn đó được "cụ thể hóa"; nghĩa là, kết quả được lưu trữ dưới dạng bảng MyISAM trung gian. (MySQL gọi nó là "bảng dẫn xuất" và tên mà họ sử dụng có ý nghĩa, khi bạn hiểu các hoạt động mà MysQL thực hiện.)

Điểm mấu chốt là chỉ mục bạn đã xác định trên happened_in MySQL không được sử dụng khi nó chạy truy vấn hình thành định nghĩa dạng xem.

Sau khi "bảng dẫn xuất" trung gian được tạo, THÌ truy vấn bên ngoài được thực thi, sử dụng "bảng dẫn xuất" đó làm nguồn hàng. Đó là khi truy vấn bên ngoài chạy happened_in = 2006 vị từ được đánh giá.

Lưu ý rằng tất cả các hàng từ truy vấn chế độ xem đều được lưu trữ, (trong trường hợp của bạn) là hàng cho MỌI giá trị của happened_in , không chỉ là cái mà bạn chỉ định một vị từ bình đẳng trong truy vấn bên ngoài.

Cách xử lý các truy vấn chế độ xem có thể "không mong muốn" đối với một số người và đây là một lý do mà việc sử dụng "chế độ xem" trong MySQL có thể dẫn đến các vấn đề về hiệu suất, so với cách các truy vấn chế độ xem được xử lý bởi các cơ sở dữ liệu quan hệ khác.

Cải thiện hiệu suất của truy vấn chế độ xem với chỉ mục bao quát phù hợp

Với định nghĩa chế độ xem và truy vấn của bạn, điều tốt nhất bạn sẽ nhận được sẽ là phương pháp truy cập "Sử dụng chỉ mục" cho truy vấn chế độ xem. Để có được điều đó, bạn cần có một chỉ mục bao trùm, ví dụ:

... ON highscores (player, happened_in, score).

Đó có thể là chỉ mục có lợi nhất (hiệu suất khôn ngoan) cho định nghĩa chế độ xem hiện tại và truy vấn hiện tại của bạn. Trình phát player là cột đứng đầu vì bạn có một vị từ bình đẳng trên cột đó trong truy vấn dạng xem. happened_in là cột tiếp theo, vì bạn đã có một hoạt động GROUP BY trên cột đó và MySQL sẽ có thể sử dụng chỉ mục này để tối ưu hóa hoạt động GROUP BY. Chúng tôi cũng bao gồm score vì đó là cột duy nhất khác được tham chiếu trong truy vấn của bạn. Điều đó làm cho chỉ mục trở thành chỉ mục "bao trùm", bởi vì MySQL có thể đáp ứng truy vấn đó trực tiếp từ các trang chỉ mục mà không cần phải truy cập bất kỳ trang nào trong bảng bên dưới. Và điều đó cũng tốt khi chúng ta sẽ thoát khỏi kế hoạch truy vấn đó:"Sử dụng chỉ mục" mà không "Sử dụng tệp tin".

So sánh hiệu suất với truy vấn độc lập không có bảng dẫn xuất

Bạn có thể so sánh kế hoạch thực thi cho truy vấn của mình so với chế độ xem so với một truy vấn độc lập tương đương:

SELECT player
     , MAX(score) AS highest_score
     , happened_in
 FROM highscores
WHERE player = 24
  AND happened_in = 2006
GROUP
   BY player
    , happened_in

Truy vấn độc lập cũng có thể sử dụng chỉ mục bao trùm, ví dụ:

... ON highscores (player, happened_in, score)

nhưng không cần hiện thực hóa bảng MyISAM trung gian.

Tôi không chắc rằng bất kỳ câu trả lời nào trước đây cung cấp câu trả lời trực tiếp cho câu hỏi bạn đang hỏi.

Hỏi:Làm cách nào để MySQL sử dụng INDEX cho truy vấn chế độ xem?

A:Xác định một INDEX phù hợp mà truy vấn chế độ xem có thể sử dụng.

Câu trả lời ngắn gọn là cung cấp một "chỉ mục bao gồm" (chỉ mục bao gồm tất cả các cột được tham chiếu trong truy vấn chế độ xem). Các cột hàng đầu trong chỉ mục đó phải là các cột được tham chiếu với các vị từ bình đẳng (trong trường hợp của bạn là cột player sẽ là cột hàng đầu vì bạn có player = 24 vị ngữ trong truy vấn. Ngoài ra, các cột được tham chiếu trong GROUP BY phải là các cột đứng đầu trong chỉ mục, điều này cho phép MySQL tối ưu hóa GROUP BY hoạt động, bằng cách sử dụng chỉ mục thay vì sử dụng một hoạt động sắp xếp.

Điểm mấu chốt ở đây là truy vấn chế độ xem về cơ bản là một truy vấn độc lập; kết quả từ truy vấn đó được lưu trữ trong bảng "dẫn xuất" trung gian (bảng MyISAM được tạo khi truy vấn đối với chế độ xem được chạy.

Sử dụng các khung nhìn trong MySQL không nhất thiết là một "ý tưởng tồi", nhưng tôi thực sự cảnh báo những người chọn sử dụng các khung nhìn trong MySQL để biết cách MySQL xử lý các truy vấn tham chiếu đến các khung nhìn đó. Và cách xử lý truy vấn chế độ xem của MySQL khác (đáng kể) với cách xử lý truy vấn chế độ xem bởi các cơ sở dữ liệu khác (ví dụ:Oracle, SQL Server).



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Hibernate có thể hoạt động với cú pháp ON DUPLICATE KEY UPDATE của MySQL không?

  2. Cách tạo CRUD đơn giản bằng PHP và MySQL một cách dễ dàng

  3. Ngăn gia tăng tự động InnoDB TRÊN KHÓA DUPLICATE

  4. Cách cài đặt MySQL Workbench trên Windows

  5. Cách nhận dữ liệu tuần hiện tại trong MySQL