الخلية غروبويز قضايا الأداء الأقصى على جدول صف مليون
-
13-12-2019 - |
سؤال
أحاول أن أجد طريقة مباشرة لتحسين الأداء للمنتديات نشطة جدا حيث يوجد عدد كبير من المشاركات والخلية لم تعد قادرة على القيام أنواع الجدول في الذاكرة ولا يبدو أن الاستفادة الكاملة من الفهارس.
يجد هذا الاستعلام البسيط أحدث منشور في كل موضوع للمستخدم لتحديد ما إذا كان لديه أي ردود منذ ذلك الحين (بمقارنة وقت الموضوع لاحقا)
SELECT p.*, MAX(post_time) as post_time FROM forum_posts AS p
WHERE p.poster_id = '1' AND p.post_status = '0'
GROUP BY p.topic_id
ORDER BY post_time DESC
LIMIT 50
بسيطة ، طاولة مسطحة تبدو شيئا من هذا القبيل
post_id | poster_id | topic_id | post_status | post_time | post_text
ومع ذلك ، فإن الأداء ينهار عندما يكون هناك مليون منشور ويكون لدى المستخدم نفسه عشرات الآلاف من المنشورات.الخلية يمكن إما لم يعد فرز الجدول في الذاكرة أو هناك عدد كبير جدا من الصفوف لمسح.يمكن أن يستغرق ما يصل إلى 3 ثوان في استخدام العالم الحقيقي وهو أمر غير مقبول إمهو لأنه ارتفاع وحدة المعالجة المركزية خلال ذلك الوقت وتباطؤ الجميع إلى أسفل.
أنا يمكن أن تجعل أي مزيج من مؤشر بالطبع ، ولكن يبدو أن الخلية في الغالب ترغب في استخدام التحرير والسرد من
poster_id + post_time
لذلك فهو يختار فقط 50 ألف منشور لمستخدم واحد من المليون ثم يبدأ التجميع حسب معرف الموضوع والفرز.لا يبدو أن إضافة معرف الموضوع بشكل غريب إلى مزيج الفهرس يساعد في الأداء ، على الرغم من أنه قد يكون ترتيب حقول الفهرس?
لقد حاولت كتابة رابط مكافئ بدلا من ذلك حتى أتمكن من استخدام أكثر من فهرس واحد ولكني أواجه مشاكل في حقيقة أنه يجب تصفية كل جانب حسب حالة المنشور والملصق.
كنت أفكر أنه سيكون أسرع ، على الأقل بالنسبة للصفحات القليلة الأولى ، إذا كان من الممكن إجراء الخلية لفرز البيانات أولا عبر فهرسها حسب وقت النشر ثم البدء في اختيار معرف الموضوع المميز للمستخدم بترتيب تنازلي.أعتقد أن ذلك سيتطلب استعلاما فرعيا ولست متأكدا من أن الاستعلام الفرعي للنتيجة 50 ألف سيكون أفضل ، ولا يزال بحاجة إلى جدول مؤقت.
بالطبع سيكون الحل الأساسي هو زيادة التصميم الأساسي بحيث يكون هناك جدول آخر يخزن فقط الحد الأقصى لوقت النشر لكل مستخدم في كل موضوع ولكن هذا تغيير كبير جدا ما لم يتم العثور على حل آخر.
شكرا لك على أي اقتراحات!
إضافة مثال العالم الحقيقي وشرح:
سجل بطيء
# Query_time: 2.751334 Lock_time: 0.000056 Rows_sent: 40 Rows_examined: 48286
SELECT p.*, MAX(post_time) as post_time FROM forum_posts AS p WHERE p.poster_id = '2' AND p.post_status = '0' GROUP BY p.topic_id ORDER BY post_time DESC LIMIT 7000, 40;
شرح
select_type table type possible_keys key key_len ref rows Extra
SIMPLE p ref poster_time poster_time 4 const 27072 Using where; Using temporary; Using filesort
المحلول
أولا ، إصلاح الاستعلام الخاص بك لتقديم نتائج محددة:
SELECT p.topic_id,
MAX(post_time) as post_time
FROM forum_posts AS p
WHERE p.poster_id = '1' AND p.post_status = '0'
GROUP BY p.topic_id
ORDER BY post_time DESC
LIMIT 50 ;
ثم جربه بعد إضافة فهرس على (post_status, poster_id, topic_id, post_time)
.