حدد أحدث سجلات أحدث من الجدول وجعل هذا سريعا، كيف؟
-
19-09-2019 - |
سؤال
يوم جيد، لدي سؤال أعاني من الكثير، نأمل أن يجد شخص ما بالفعل حل ذكي لهذا (أستخدم MySQL).
لدي جدول مثل هذا:
Table `log`
----------
id
inserted
message
user_id
هدفي هو تحديد آخر سجل مدرج للمستخدم وجعل هذا سريعا. جدول السجل ضخم (حوالي 900K سجلات)، لذلك كان نهجي الأول:
SELECT * FROM `log`
LEFT JOIN `users` ON `users`.`id` = `log`.`user_id`
WHERE `id` IN
(
SELECT MAX(`id`) FROM `log` GROUP BY `user_id`
)
ولكن يبدو أنه يحسب الاستعلام الاستقبالي مقابل كل صف (شرح الاستعلام المعتمد). عندما أقسيم هذا الاستعلام لشخصين:
SELECT MAX(`id`) FROM `log` GROUP BY `user_id`
و
SELECT * FROM `log`
LEFT JOIN `users` ON `users`.`id` = `log`.`user_id`
WHERE `id` IN (....ids from first query...)
من المقبول تشغيل. هل يمكن أن يتحقق هذا من قبل استعلام واحد؟
المحلول
بالإضافة إلى استخدام المجموعة من أجل جلب أقصى حد كبير، ربما ترغب في جعلها عملية استقبالية غير مرتبطة لجلب حقول إضافية للصفوف المحددة من الجدول.
SELECT
la.user_id,la.message
FROM
`log` as la
INNER JOIN
(
SELECT
user_id, MAX(id) AS maxid
FROM
`log`
GROUP BY
user_id
) as lb
ON
la.id = lb.maxid
هذا يعمل بشكل أفضل / أسرع إذا كان لديك فهرس
KEY `foo` (`user_id`,`id`)
ولكن حتى من دون هذا المفتاح الأداء هو النزول.
نصائح أخرى
ماذا عن
SELECT user_id, max(id) FROM `log` GROUP BY user_id
?
سيحصل هذا على أقصى قدر من المعرف لكل مستخدم في جدول السجل، كل ذلك في استعلام واحد!
إذا كنت تبحث دائما عن تسجيل الدخول لمستخدم معين، فإن تقسيم ملف السجل من خلال USER_ID سوف يسرع الأمور كثيرا. إذا تم تقسيم الجدول بواسطة المستخدم وفهرسه بالمعرف، فسيتم تشغيل الاستعلام بسرعة كبيرة.
تحرير: انظر استعلام دومينيك
بالإضافة إلى ذلك، كنت أتأكد من أن لديك فهرس على user_id.
تحرير: المعمم