الصفحةُ البطيئة استعلامٌ بطيءٌ واحد في العادة، لا خادمٌ بطيء. وMySQL تخبرك أيُّها هو إن سألت، والسؤالُ يكلّف إعدادًا واحدًا.

شغّله

SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';

الثانيةُ الواحدة حدٌّ جيّد للبداية: تلتقط ما يعني بلا ملء القرص. واجعله دائمًا في my.cnf حين تعرف أنّه مفيد.

اقرأه

mysqldumpslow -s t -t 10 /var/log/mysql/slow.log

هذا يرتّب بالزمن الكلّيّ ويطبع أسوأ عشرة. فاستعلامٌ يأخذ 0.2 ثانية ويعمل ثلاثمائة مرّةٍ في الصفحة أسوأ من استعلامٍ يأخذ ثانيتين مرّةً واحدة، وهذا الترتيب يُظهر ذلك.

اسأل لِمَ هو بطيء

EXPLAIN SELECT ... ;
  • type: ALL — مسحٌ كاملٌ للجدول. كلُّ صفٍّ يُقرأ للإجابة عن سؤالٍ واحد.
  • rows: رقمٌ كبير — كم صفًّا يتوقّع أن يقرأ. قارنه بكم تتوقّع أن يعود إليك.
  • Using filesort — فرزٌ في الذاكرة أو على القرص لأنّ لا فهرسَ يعطي الترتيب.

الفهرسُ الذي يصلحه عادةً

فهرسٌ على العمود الذي في جملة WHERE. وإن كان الاستعلام يرشّح على عمودين فَفَهرسٌ واحد عليهما معًا، بالترتيب الذي يستعملهما به الاستعلام.

CREATE INDEX idx_orders_customer_created ON orders (customer_id, created_at);
والفهرسُ ليس مجّانيًّا: يُبطئ الكتابة ويأخذ قرصًا. أضف الذي سمّاه السجلّ ثمّ قِس ثانيةً. فإضافةُ فهرسٍ إلى كلّ عمودٍ هي كيف تبطؤ قاعدةُ بيانات.
ونفّذ EXPLAIN ثانيةً بعد إضافته. فإن بقي type على ALL فالفهرسُ لا يُستعمَل — والسببُ عادةً أنّ الاستعلام يلفّ العمود في دالّة، ولا فهرسَ يُغني عن ذلك.