2010-01-29 41 views
5

Tôi có thể tham gia bằng cách nào đó bằng cách nào đó và tránh sử dụng khác biệt trong truy vấn MySQL sau đây. invite_by_id hiển thị id người dùng của người đã mời người dùng này.Làm cách nào để tối ưu hóa truy vấn lồng nhau?

SELECT 
    user1.id, count(distinct user2.id) AS theCount, count(distinct user3.id) AS theCount2 
FROM 
    users AS user1 
LEFT OUTER JOIN 
    users AS user2 ON user2.invited_by_id=user1.id 
LEFT OUTER JOIN (
    SELECT id, invited_by_id FROM users WHERE signup_date >= NOW() - INTERVAL 30 DAY 
) AS user3 ON user3.invited_by_id=user1.id 
GROUP BY user1.id; 
+0

Tại sao bạn cần phân biệt? Dường như với tôi rằng người dùng X chỉ nên được người dùng Y * một lần * mời. –

+0

@Lieven Kể từ khi bảng đang được tham gia trong hai lần bạn có thể nhận được hàng trùng lặp. –

Trả lời

1

Hãy thử một cái gì đó như thế này, tôi đã thay đổi tên bảng truy vấn phụ để làm cho nó rõ ràng hơn một chút:

Select 
    user.id, 
    all_time.total AS theCount, 
    last_month.total AS theCount2 
From users AS user 
Left Outer Join 
    (Select Count(id) as total, invited_by_id 
    From users 
    Group By invited_by_id) as all_time 
     On all_time.invited_by_id = user.id 
Left Outer Join 
    (Select Count(id) as total, invited_by_id 
    From users 
    Where signup_date >= NOW() - INTERVAL 30 DAY 
    Group By invited_by_id) AS last_month 
     On last_month.invited_by_id = user.id 

Nếu đây là một cái gì đó bạn thường xuyên chạy, đảm bảo rằng user.invited_by_id được lập chỉ mục!

1

Nếu bạn đang chạy một phiên bản của MySQL lớn hơn 5.0.37 bạn có một Profiler sẵn cho bạn mà có thể cung cấp cho bạn một ý tưởng khá tốt của nơi tắc nghẽn được trên bất kỳ truy vấn. Đó có thể là một điểm khởi đầu tốt - bạn có thể có thể chỉnh sửa đầu ra vào câu hỏi ban đầu nếu bạn không chắc chắn về cách tốt nhất để giải thích nó.

+0

Anh ấy đang sử dụng mysql. –

+0

Điểm tốt, không biết tại sao tôi gõ nhầm điều đó. – glenatron

+0

Ah ... Điều đó có ý nghĩa hơn rất nhiều! :) –

3

Tôi giả định ở đây rằng bạn đang cố gắng tính số lần người dùng đã được mời và số lần người dùng đã được mời trong 30 ngày qua.

Trong trường hợp này bạn có thể thực hiện truy vấn với một số tiền có điều kiện đơn giản như:

select user1.id, count(user2.id) as tehCount, sum(user2.signup_date >= NOW() - INTERVAL 30 DAY) as theCount2 
from users as user1 
left outer join users as user2 on user2.invited_by_id = user1.id 
group by user1.id 

Nếu null trong theCount2 sẽ là một vấn đề, sử dụng một liên hiệp như:

coalesce(sum(user2.signup_date >= NOW() - INTERVAL 30 DAY), 0) 
Các vấn đề liên quan