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

Làm thế nào để triển khai hệ thống gắn thẻ tương tự như SO trong php / mysql?

Trước khi chúng tôi đi vào tối ưu hóa sớm , có thể hữu ích khi xem xét mẫu truy vấn sau. Nếu không có gì khác, điều này có thể được sử dụng làm đường cơ sở để đo lường hiệu quả của các tối ưu hóa có thể có.

SELECT T.Tagid, TagInfo.TagName,  COUNT(*)
FROM Items I
JOIN Tags TagInfo ON TagInfo.TagId = T.TagId
JOIN ItemTagMap T  ON I.ItemId = T.ItemId 
--JOIN ItemTagMap T1 ON I.ItemId = T1.ItemId
WHERE I.ItemId IN
  (
      SELECT ItemId 
      FROM Items
      WHERE   -- Some typical initial search criteria
         Title LIKE 'Bug Report%'   -- Or some fulltext filter instead...
         AND  ItemDate > '02/22/2008'
         AND  Status = 'C'
  )
--AND T1.TagId = 'MySql'
GROUP BY T.TagId, TagInfo.TagName
ORDER BY COUNT(*) DESC

Truy vấn con là "truy vấn thúc đẩy", tức là truy vấn tương ứng với tiêu chí ban đầu của người dùng cuối. (xem bên dưới để biết chi tiết về cách truy vấn này, được yêu cầu nhiều lần có thể phù hợp với quy trình được tối ưu hóa tổng thể) Được nhận xét là JOIN trên T1 (và có thể là T2, T3, khi một số thẻ được chọn) và, với mệnh đề WHERE, liên kết tiêu chuẩn. Chúng cần thiết khi người dùng chọn một thẻ cụ thể, cho dù là một phần của tìm kiếm ban đầu hay bằng cách sàng lọc. (Có thể hiệu quả hơn nếu đặt các phép nối này và mệnh đề ở đâu trong truy vấn phụ; thêm thông tin về những điều này bên dưới)

Thảo luận ... "Truy vấn thúc đẩy" hoặc một biến thể của nó là cần thiết cho hai mục đích riêng biệt:

  • 1 để cung cấp thông tin hoàn chỉnh danh sách ItemId cần thiết để liệt kê tất cả các thẻ được liên kết.

  • 2 để cung cấp N giá trị ItemId đầu tiên (N là kích thước trang hiển thị), nhằm mục đích tra cứu thông tin chi tiết Mặt hàng trong bảng Mặt hàng.

Lưu ý rằng danh sách đầy đủ không cần phải được sắp xếp (hoặc nó có thể có lợi khi sắp xếp theo một thứ tự khác), theo đó danh sách thứ hai cần được sắp xếp dựa trên lựa chọn của người dùng (giả sử theo Ngày, giảm dần hoặc theo Tiêu đề, tăng dần theo bảng chữ cái ). Cũng lưu ý rằng nếu có bất kỳ thứ tự sắp xếp nào được yêu cầu, chi phí của truy vấn sẽ ngụ ý xử lý danh sách hoàn chỉnh (do chính SQL tối ưu hóa kỳ lạ và / hoặc một số bất chuẩn hóa, SQL cần "xem" các bản ghi cuối cùng trong danh sách đó , trong trường hợp chúng thuộc về hàng đầu, hãy sắp xếp hợp lý).

Thực tế thứ hai này có lợi cho việc có cùng một truy vấn cho cả hai mục đích, danh sách tương ứng có thể được lưu trữ trong một bảng tạm thời. Quy trình chung sẽ là nhanh chóng tra cứu các bản ghi N Mục hàng đầu với thông tin chi tiết của chúng và trả lại thông tin này cho ứng dụng ngay lập tức. Sau đó, ứng dụng có thể nhận được danh sách các Thẻ để sàng lọc. Danh sách này sẽ được tạo ra với một truy vấn tương tự như ở trên, trong đó truy vấn con được thay thế bằng "select * from tạm thờiTable." Rất may là trình tối ưu hóa SQL sẽ quyết định sắp xếp danh sách này (trong một số trường hợp), hãy để nó làm điều đó, thay vì đoán thứ hai và sắp xếp nó một cách rõ ràng.

Một điểm khác cần xem xét là có thể đưa (các) tham gia trên bảng ItemTagMap vào bên trong "truy vấn lái xe" thay vì như được hiển thị ở trên. Có lẽ tốt nhất là nên làm như vậy, vì cả hiệu suất và vì nó sẽ tạo ra danh sách phù hợp cho mục đích số 2 (hiển thị một trang các mục).

Truy vấn / luồng được mô tả ở trên có thể sẽ mở rộng quy mô khá tốt, ngay cả trên phần cứng tương đối khiêm tốn; dự kiến ​​vào khoảng 1/2 Triệu + Mục, với số lượt tìm kiếm của người dùng liên tục có thể lên đến 10 mỗi giây. Một trong những yếu tố chính là tính chọn lọc của các tiêu chí tìm kiếm ban đầu.

Ý tưởng tối ưu hóa

  • [Tùy thuộc vào các trường hợp tìm kiếm điển hình và vào số liệu thống kê], có thể hợp lý khi không chuẩn hóa bằng cách đưa (thực sự là sao chép) một số trường của Mục vào bảng ItemTagMap. Các trường ngắn đặc biệt có thể được "chào đón" ở đó.
  • Khi dữ liệu tăng lên trong hàng triệu + Mục, chúng tôi có thể khai thác mối tương quan mạnh mẽ điển hình của một số thẻ (ví dụ:trong SO, PHP thường đi kèm với MySql, btw thường không có lý do chính đáng ...), bằng nhiều thủ thuật khác nhau. Ví dụ:việc giới thiệu các Mã thẻ "đa thẻ" có thể làm cho logic đầu vào phức tạp hơn một chút, nhưng cũng có thể làm giảm đáng kể kích thước Bản đồ.


- 'nough said! -
Kiến trúc và tối ưu hóa phù hợp nên được lựa chọn dựa trên các yêu cầu thực tế và của hồ sơ thống kê dữ liệu hiệu quả ...



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Nhập tệp .sql MySQL lớn trên Windows bằng Force

  2. Phân tích cú pháp ngày trong MySQL

  3. Thông báo ClusterControl 1.7.5:Bảo trì và hỗ trợ cụm nâng cao cho PostgreSQL 12 và MongoDB 4.2

  4. Định dạng ngày chèn mysql PHP

  5. Quản lý tài khoản người dùng, vai trò, quyền, xác thực PHP và MySQL - Phần 5