MySQL: انضم واستخدام الفهرس في طلب عن طريق الاستعلام
-
28-09-2019 - |
سؤال
لدي نظام يشبه ميزة سؤال وجواب من StackOverflow. الفرق الرئيسي هو قبعة كل سؤال له وقت انتهاء الصلاحية:
CREATE TABLE questions (
id INT NOT NULL AUTO_INCREMENT,
title CHAR(100) NOT NULL,
details TEXT
PRIMARY KEY (id)
)
CREATE TABLE answers (
id INT NOT NULL AUTO_INCREMENT,
question_id INT NOT NULL
details TEXT
expiration_datetime DATETIME
score INT
PRIMARY KEY (id)
)
أرغب في عرض سؤال مع أفضل الإجابات غير المعروضة التي تم طلبها بواسطة SCORE. أفكر في شيء مثل هذا:
SELECT * FROM questions, answers
WHERE questions.id=1 AND questions.id=answers.question_id AND answers.expiration_datetime > NOW()
ORDER BY answers.score DESC LIMIT 10
بعض الأسئلة:
1) هل الاستعلام فوق الطريقة الأكثر فاعلية للقيام بما أريد؟ كيف يختلف عن استخدام Join بشكل صريح مثل:
SELECT * FROM questions JOIN answers ON questions.id=answers.question_id
WHERE questions.id=1 AND answers.expiration_datetime > NOW()
ORDER BY answers.score DESC LIMIT 10
2) كيفية جعل فهرس استخدام الاستعلام الخاص بي؟ أفكر في إضافة هذا الفهرس إلى إجابات الجدول:
INDEX (question_id, expiration_datetime, score)
هل سيعمل الفهرس أعلاه لاستفساري؟ لا يبدو ذلك صحيحًا لأن Expirtive_DateTime تصعد بينما أحتاج إلى درجة لأكون تنازليًا. ماذا يمكنني أن أفعل هنا؟
المحلول
يعطي الجداول مع Joinn Inner أو في البند من خطة التنفيذ نفسها. ومع ذلك ، فإن الأول أكثر سهولة في القراءة (وهذا ما يوحيه المعيار منذ عام 1992).
ستستخدم RDBMS فهرس كلما كان ذلك ممكنًا. عادة ما يكون من الجيد طباعة خطة التنفيذ (EXPLAIN SELECT * FROM -- ...
). ومع ذلك ، لاحظ أن إنشاء فهرس أعمدة متعددة يمكن أن يكون صعبًا. في حالتك ، يمكنك استخدام الفهرس على Question_id ولكن ليس على Expiration_DateTime أو النتيجة لأنها ليست الأعمدة الأولى للفهرس. سيكون عليك أن تصنع ثلاثة فهرس مختلف.
PS SELECT * غير موصى به. اكتب دائمًا الأعمدة التي تحتاجها (من السهل القراءة وإعادة قراءة) فقط أذكر الأعمدة التي ستستخدمها. لا جدوى من تحديد ، على سبيل المثال ، initial_date إذا لم تستخدم هذا العمود أبدًا في البرنامج النصي الخاص بك!