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

Tối ưu hóa truy vấn mysql (thích / không thích)

Về mặt hiệu suất, những truy vấn phụ tương quan đó có thể ăn bữa trưa của bạn. Và ngấu nghiến cả hộp ăn trưa của bạn, đối với các bộ lớn, vì cách MySQL xử lý chúng. Mỗi truy vấn con đó được thực thi cho mọi hàng được trả về trong truy vấn bên ngoài. Và điều đó có thể rất đắt đối với các bộ lớn.

Một cách tiếp cận thay thế là sử dụng chế độ xem nội tuyến để hiện thực hóa lượt thích và lượt không thích cho tất cả nội dung, sau đó thực hiện thao tác kết hợp với nội dung đó.

Tuy nhiên, cách tiếp cận này cũng có thể tốn kém, đặc biệt là khi bạn chỉ cần "đếm" phiếu bầu cho chỉ một vài hàng nội dung, trong số bazi tỷ hàng. Thông thường, có một vị từ từ truy vấn bên ngoài cũng có thể được kết hợp vào dạng xem nội tuyến, để giới hạn số hàng cần được kiểm tra và trả về.

Chúng tôi muốn sử dụng một phép nối OUTER cho dạng xem nội tuyến đó, vì vậy nó trả về một kết quả tương đương với truy vấn của bạn; trả về một hàng từ content khi không có hàng nào phù hợp trong vote bảng.

SELECT [... BUNCH OF FIELDS ...]
     , COALESCE(v.likes,0) AS likes
     , COALESCE(v.dislikes,0) AS dislikes
     , COALESCE(v.myvote,'.Constants::NO_VOTE.') AS myvote
  FROM content c
  LEFT
  JOIN ( SELECT vt.cId
              , SUM(vt.vote = '.Constants::LIKE.') AS likes
              , SUM(vt.vote = '.Constants::DISLIKE.') AS dislikes
              , MAX(IF(vt.userId = '.USER_ID.',vt.vote,NULL)) AS myvote
           FROM votes vt
          GROUP
             BY vt.cId
       ) v
    ON v.cId = c.contentId

       [... OTHER STUFF ... ]

Lưu ý rằng truy vấn chế độ xem nội tuyến (bí danh là v ) sẽ xem xét MỌI hàng đơn từ vote bàn. Nếu bạn chỉ cần một tập hợp con, thì hãy cân nhắc việc thêm một vị từ thích hợp (trong mệnh đề WHERE hoặc dưới dạng JOIN vào một bảng khác). Không có dấu hiệu nào từ [... OTHER STUFF ...] trong truy vấn của bạn cho dù nó chỉ trả về một vài hàng từ content hoặc nếu bạn đang cần tất cả các hàng vì bạn đang sắp xếp theo likes , v.v.

Đối với một số lượng nhỏ các hàng được chọn từ content bảng, bằng cách sử dụng các truy vấn con tương quan (như trong truy vấn của bạn) thực sự có thể nhanh hơn so với việc hiện thực hóa một chế độ xem nội tuyến khổng lồ và thực hiện thao tác kết hợp với nó.

Ồ ... và đối với cả hai truy vấn, không cần phải nói rằng một chỉ mục thích hợp trên vote bảng có cột ở đầu là cId sẽ có lợi cho hiệu suất. Đối với dạng xem nội tuyến, bạn không muốn chi phí của MySQL phải thực hiện filesort hoạt động trên tất cả các hàng đó để thực hiện GROUP BY. Và đối với các truy vấn con có tương quan, bạn muốn chúng sử dụng quét phạm vi chỉ mục, không phải quét toàn bộ.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL Lựa chọn dữ liệu từ ba bảng có liên quan

  2. Nhận tuổi từ DOB trong MySQL

  3. Cách chạy Truy vấn SQL thô với Zend Framework 2

  4. Làm thế nào để chuyển đổi tất cả các bảng trong cơ sở dữ liệu thành một đối chiếu?

  5. Tôi có thể tự động điều chỉnh giá trị của trường tăng dần trong cơ sở dữ liệu không?