Tối ưu truy vấn MySQL
Có rất nhiều cách để giải quyết vấn đề lấy dữ liệu từ các bảng table trong MySQL, khi đi làm đôi lúc bạn gặp một bài toán như là tối ưu một tác vụ trên trang hoặc chức năng nào đó trong các dự án lập trình, tác vụ yêu cầu phải thực thi nhanh. Do đó bạn phải tối ưu giao diện + tối ưu truy vấn cơ sở dữ liệu. Các bạn đã làm việc với database MySQL đều biết truy vấn nhiều lần thì sẽ làm giảm tốc độ xử lý. Do đó nên sử dụng Subquery MySQL để truy vấn một lần.
Ví dụ: Truy vấn một lần lây ra 2 sản phẩm của mỗi danh mục product category
Chúng ta có table[products] có 2 danh mục category là: 1,2 mỗi danh mục đang có 3 sản phẩm. Bây giờ các bạn phát biểu truy vấn MySQL làm sao để lấy ra 2 sản phẩm của mỗi danh mục?
Có rất nhiều cách để giải quyết bài toán trên, trong bài viết MySQL nhantam giới thiệu cách truy vấn một lần để lấy n sản phẩm theo các danh mục.
MySQL cách truy vấn chỉ lấy 2 sản phẩm của mỗi danh mục category
// Truy vấn chạy cả trên MySQL, MariaDB
SELECT
id, category, product_name, n
FROM
(SELECT @prev := '', @n := 0 ) init
JOIN
(
SELECT @n := if(category != @prev, 1, @n + 1) AS n,
@prev := category,
id, category, product_name, product_description
FROM products
) x
WHERE n <= 2
ORDER BY category;
// Kết quả truy vấn MySQL bên trên như hình sau:
Các bạn có thể lấy n sản phẩm bằng cách thay đổi giá trị n ở chỗ WHERE
WHERE n <= 3
Hoặc truy vấn cho MariaDB
// Truy vấn chị hoạt động trên MariaDB
SELECT
id, category, product_name
FROM (
SELECT *,
IF( @prev <> category,
@rownum := 1,
@rownum := @rownum+1
) AS rank,
@prev := category,
@rownum
FROM (
SELECT * FROM products
ORDER BY category, rand()
) random_prodcts
) products_ranked
WHERE rank <= 2;
Xem thêm tại: >> Select 2 products from each category in MySQL
Cách 2
Một số PHP framework truy vấn MySQL hoặc MariaDb với việc khai báo biến variables trong câu truy vấn thì nó cho kết quá chưa đúng(Vấn đề này là bug trong các class DB của các framework), lúc này các bạn dùng cách 2 bên dưới:
SELECT id, category, product_name as count FROM
(
SELECT id, category, product_name,
row_number() OVER (PARTITION BY categoryORDER BY category) AS row_number,
COUNT(*) OVER (PARTITION BY categoryORDER BY category) as itemcount
FROM products p
) a
WHERE a.row_number < 3
Chúc các bạn thành công
nhantam
Lập trình phền mềm trên mền web tại Panpic