سؤال

يوم جيد، لدي سؤال أعاني من الكثير، نأمل أن يجد شخص ما بالفعل حل ذكي لهذا (أستخدم 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.

تحرير: المعمم

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top