كيفية تحسين استعلام متداخل؟
-
23-09-2019 - |
سؤال
هل يمكنني الانضمام بطريقة أو بأخرى إلى الجداول وتجنب استخدام متميز في استعلام MySQL التالي. يعرض uppited_by_id معرف المستخدم لمن قام بدعوة هذا المستخدم.
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;
المحلول
جرب شيئًا كهذا ، لقد غيرت أسماء الجدول الفرعية لتوضيحها أكثر وضوحًا:
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
إذا كان هذا شيء تقوم بتشغيله كثيرًا ، فتأكد من ذلك user.invited_by_id
مفهرسة!
نصائح أخرى
أفترض هنا أنك تحاول الحصول على عدد المرات التي تمت فيها دعوة المستخدم وعدد عدد المرات التي تمت فيها دعوة المستخدم في الثلاثين يومًا الماضية.
في هذه الحالة ، يمكنك إجراء الاستعلام بمجموع مشروط بسيط على النحو التالي:
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
إذا كانت الفارغات في thecount2 ستكون مشكلة ، فاستخدم coalesce على النحو التالي:
coalesce(sum(user2.signup_date >= NOW() - INTERVAL 30 DAY), 0)
إذا كنت تدير إصدارًا من MySQL أكبر من 5.0.37 ، فلديك ملف البروفيلر متاح لك يمكن أن تمنحك فكرة جيدة عن المكان الذي توجد فيه الاختناقات في أي استعلام. قد تكون هذه نقطة انطلاق جيدة- ربما يمكنك تعديل الإخراج إلى السؤال الأصلي إذا لم تكن متأكدًا من أفضل طريقة لتفسيره.