2010-10-26 45 views
5

Tôi có truy vấn này trong một bảng với khoảng 100k bản ghi, nó chạy khá chậm (3-4s), khi tôi đưa ra nhóm nó nhanh hơn nhiều (ít hơn 0,5s). Tôi khá thua lỗ phải làm gì để khắc phục điều này:mysql "nhóm bởi" truy vấn rất chậm

SELECT msg.id, 
     msg.thread_id, 
     msg.senderid, 
     msg.recipientid, 
     from_user.username AS from_name, 
     to_user.username AS to_name 
FROM msgtable AS msg 
LEFT JOIN usertable AS from_user ON msg.senderid = from_user.id 
LEFT JOIN usertabe AS to_user ON msg.recipientid = to_user.id 
GROUP BY msg.thread_id 
ORDER BY msg.id desc 

msgtable có chỉ số về thread_id, id, senderidrecipientid.

giải thích lợi nhuận:

id select_type table type possible_keys key key_len ref rows Extra 
1 SIMPLE msg ALL NULL NULL NULL NULL 162346 Using temporary; Using filesort 
1 SIMPLE from_user eq_ref PRIMARY PRIMARY 4 db.msg.senderid 1  
1 SIMPLE to_user eq_ref PRIMARY PRIMARY 4 db.msg.recipientid 1 

Bất kỳ ý tưởng làm thế nào để tăng tốc độ này lên khi trả lại kết quả tương tự (có nhiều tin nhắn mỗi chủ đề, tôi muốn quay trở lại chỉ có một thông điệp cho mỗi thread trong truy vấn này).

cảm ơn trước.

+1

Còn các chỉ mục 'có thể sử dụng được thì sao? Bạn có thể chạy 'EXPLAIN ' và đăng kết quả không? – Frankie

+1

Thông thường, bạn phải khai báo tất cả các cột được đề cập trong SELECT không được đóng gói bởi các hàm tổng hợp (COUNT, SUM, MIN, MAX, vv) trong GROUP BY. 'DISTINCT' có thể phục vụ bạn tốt hơn trong tình huống này không? –

+0

Tại sao lại tham gia trái? Mỗi thư không yêu cầu người nhận và người gửi phải không? –

Trả lời

1

thử điều này:

select m.thread_id, m.id, m.senderid, m.recipientid, 
     f.username as from_name, t.username as to_name 
from msgtable m 
join usertable f on m.senderid = f.id 
join usertable t on m.recipientid = t.id 
where m.id = (select MAX(id) from msgtable where thread_id = m.thread_id) 

Hoặc này:

select m.thread_id, m.id, m.senderid, m.recipientid, 
     (select username from usertable where id = m.senderid) as from_name, 
     (select username from usertable where id = m.recipientid) as to_name 
from msgtable m 
where m.id = (select MAX(id) from msgtable where thread_id = m.thread_id) 

Tại sao các bảng sử dụng trái tham gia? Tin nhắn có thể bị thiếu hoặc từ? ..

+0

Cảm ơn một triệu, tôi đã thử cả hai tùy chọn - tùy chọn đầu tiên khoảng 1,5 giây, tùy chọn thứ hai khoảng 2 giây. bất cứ điều gì khác tôi có thể làm để đưa nó xuống nhiều hơn? –

+0

@Sherif tốt, bạn có thực sự cần TẤT CẢ các chủ đề cùng một lúc không? ... Có cột thời gian nào có thể được sử dụng để cắt giảm các dữ liệu cần thiết không? – Fosco

+0

@ Forsco, thực sự truy vấn này được dịch sang là một số (*) truy vấn được chọn bởi một lớp phân trang - có tôi cần tất cả các chủ đề vì đây là chức năng quản trị ... –

0

Vấn đề lớn nhất là bạn không có chỉ mục có thể sử dụng trên msgtable. Tạo chỉ mục trên ít nhấtsenderidrecipientid và nó sẽ giúp tốc độ truy vấn của bạn, vì nó sẽ giới hạn số lượng kết quả cần được quét.

+0

Tôi có chỉ mục về những câu hỏi được cập nhật ở trên. –

Các vấn đề liên quan