2011-12-25 30 views
6

Các truy vấn sau đây là tương đối chậm (0,7 giây với ~ 6k hàng)MySQL chậm nhóm bằng/trật tự bởi

SELECT items.*, COUNT(transactions.ID) 
    FROM items 
    INNER JOIN users ON (items.USER = users.ID) 
    LEFT JOIN transactions ON (items.id = transactions.item) 
    WHERE items.ACTIVE = 1 
    AND items.DELETED_AT IS NULL 
    GROUP BY items.ID 
    ORDER BY items.DATE DESC 
    LIMIT 20 

Nhưng tốc độ tăng đáng kể khi ra lệnh bởi items.ID DESC thay vì items.DATE. Các giao dịch tham gia là một bảng lớn (~ 250k hàng) và là một-nhiều. Cột ngày tháng có chỉ mục.

Có cách nào để cải thiện tổng thể hiệu suất của ORDER BY không?

CHỈNH SỬA: lập chỉ mục trên các mục.user, transactions.item và items.date. Các mục có 49 cột, người dùng 76 và giao dịch 17.

+3

Bạn có thể cung cấp các lược đồ và đặc biệt là các chỉ mục cho ba bảng không? – TetonSig

+0

Điều duy nhất mà tôi có thể nghĩ đến là lần đầu tiên chọn các mục được lọc theo mệnh đề WHERE của bạn và được sắp xếp theo ngày trong truy vấn phụ, (hoặc trong một dạng xem, nếu MySQL không hỗ trợ ORDER BY trong truy vấn con), và sau đó trong một truy vấn kèm theo tham gia của bạn. (Tôi không viết câu trả lời này vì SO không khuyến khích câu trả lời đầu cơ.) –

+0

Bạn đã thử bao gồm 'items.DATE' trong' GROUP BY' (ở vị trí đầu tiên)? –

Trả lời

5

Các chỉ mục có thể ảnh hưởng đến hiệu suất của các điều khoản ORDER BY. Điều này có nghĩa là MySQL manual page có thể đáng giá thời gian của bạn. Về cơ bản, nếu bạn đặt hàng bởi một cột là một phần của chỉ mục mà MySQL sử dụng cho truy vấn, MySQL có thể sử dụng chỉ mục cho sắp xếp thay vì chính dữ liệu đó.

Trong truy vấn cụ thể của bạn, thực tế là cột DATE có chỉ mục không quan trọng, vì chỉ mục đó có thể không được sử dụng trong truy vấn của bạn. Câu lệnh WHERE của bạn chứa items.ACTIVEitems.DELETED_AT và nếu các cột đó có chỉ mục đang được sử dụng cho WHERE không bao gồm cột DATE thì MySQL không thể sử dụng chỉ mục để sắp xếp theo DATE và có khả năng sử dụng tệp sắp xếp.

Nếu bạn có thể đưa ra chỉ mục có thể được sử dụng bởi cả WHEREORDER BY, bạn sẽ nhận được tăng tối ưu hóa. Trong trường hợp này, items.ACTIVE có vẻ như một cột số lượng thấp, vì vậy giả sử items.DELETED_AT là một ngày, tôi có thể sẽ thử một chỉ mục như INDEX(DELETED_AT,DATE) cho bảng đó.

Sử dụng EXPLAIN SELECT... để xem thêm về những gì đang diễn ra ở đó, bạn có thể nhận thêm một số thông tin chi tiết khác.

0

Đây là những thứ có thể trợ giúp (đọc không được bảo đảm).

  1. Loại bỏ * trên các mục. * Và liệt kê từng trường riêng lẻ. 49 cột là rất nhiều bạn có thực sự cần tất cả?
  2. Thông thường động cơ tối ưu hóa các truy vấn như giới hạn các tiêu chí được xem xét trên các kết nối. Có lẽ kế hoạch được sử dụng bởi động cơ không làm điều này (cần giải thích kết quả kế hoạch để biết) để sắp xếp lại mệnh đề where và tham gia CÓ THỂ (không có khả năng) bằng cách buộc động cơ xem xét điều này. (Xem bên dưới)
  3. Rebuild bảng thống kê nếu nhiều bản cập nhật, chèn, xóa có xảy ra theo thời gian, nó có thể là bảng thống kê được tắt và cần phải rebuilt cho mỗi bảng

.

SELECT items.[list fields], COUNT(transactions.ID) 
    FROM items 
    INNER JOIN users ON (items.USER = users.ID) 
     AND items.Active=1 
     AND items.DELETED_AT is Null 
    LEFT JOIN transactions ON (items.id = transactions.item) 
    GROUP BY items.ID 
    ORDER BY items.DATE DESC 
    LIMIT 20 
2

SELECT * FROM (SELECT * FROM wp_users WHERE 1 GROUP BY hạn ID 0,10) như X ORDER BY ID DESC

Các truy vấn trên hoạt động hoàn hảo, tôi đã sử dụng nó trong một cơ sở dữ liệu rất dài .Nó ORDER BY danh sách 10 OR (xx) các mặt hàng mà chúng tôi đang nhận được từ truy vấn chọn bên trong, vì vậy nó rất nhanh !!