کندی دیتابیس را نمیتوان از روی تعداد Query یا بزرگی یک جدول حدس زد. یک Query طولانی ممکن است فقط در گزارش کممصرف اجرا شود؛ در مقابل Query سیمیلیثانیهای که صدها بار در هر request تکرار میشود، بار اصلی را بسازد. برای اصلاح باید Query، caller، ورودی، execution plan و شرایط واقعی رخداد را به یک timeline وصل کنید.
پاسخ سریع: ابتدا URL یا عملیات کند را قابل تکرار کنید، زمان سمت PHP و دیتابیس را جدا بسنجید و در staging از Query Monitor استفاده کنید. برای رخدادهای production، slow query log را با آستانه محدود و بازه کوتاه زیر نظر DBA فعال کنید. Queryهای پرتکرار را normalize و بر اساس مجموع زمان، rows examined و اثر تجاری اولویتبندی کنید.
نشانههای محتمل Bottleneck دیتابیس
- TTFB بالا همراه با زمان قابلتوجه database در profiler
- wp-admin فقط در فهرست محصول، سفارش یا جستوجو کند است
- CPU یا I/O دیتابیس همزمان با endpoint مشخص بالا میرود
- lock wait یا connection queue در ساعات پرترافیک
- کندی با افزایش تعداد رکورد شدیدتر میشود
- job پسزمینه batchهای بزرگ و Query تکراری اجرا میکند
این نشانهها کافی نیستند؛ API خارجی، PHP lock یا کمبود worker نیز میتواند TTFB مشابه بسازد.
مرحله اول: سناریوی کند را دقیق تعریف کنید
«سایت کند است» ورودی تشخیصی خوبی نیست. URL، نقش کاربر، فیلتر، تعداد آیتم، زمان رخداد و cache state را ثبت کنید. مثال: «باز کردن صفحه دوم سفارشها برای مدیر در ساعت اوج ۹ ثانیه طول میکشد» قابل تکرار و اندازهگیری است. صفحه اصلی ناشناس نماینده wp-admin یا checkout نیست.
Query Monitor را کجا استفاده کنیم؟
Query Monitor میتواند Queryهای یک request، زمان، component/caller و خطاهای HTTP/PHP را نشان دهد. آن را ترجیحاً روی staging با داده نزدیک به production نصب کنید. profiler و backtrace سربار دارند؛ فعال نگهداشتن آن برای همه کاربران production یا نمایش نوار مدیریت به افراد غیرمجاز مناسب نیست.
- همان request را چند بار با شرایط ثابت اجرا کنید.
- Queryهای کند، تکراری و خطادار را جدا کنید.
- component و caller را ثبت کنید.
- زمان کل database را با زمان کل request مقایسه کنید.
- افزونه مظنون را روی clone کنترلشده غیرفعال و دوباره اندازه بگیرید.
برای نسبت دادن مؤلفه، روش پیدا کردن افزونه کند وردپرس را دنبال کنید؛ آخرین تابع در stack الزاماً علت طراحی Query نیست.
Slow Query Log چه چیزی اضافه میکند؟
ابزار داخل وردپرس یک request را میبیند، اما slow log در سطح MySQL/MariaDB میتواند cron، CLI، API و همه workerها را پوشش دهد. فعالسازی، پارامترها و مسیر log به نسخه و سرویس مدیریتشده وابسته است. logging میتواند I/O و داده حساس تولید کند؛ retention، permission، فضای دیسک و زمان خاموشکردن آن باید از قبل مشخص باشد.
آستانه را آنقدر پایین نگذارید که زیر بار واقعی دیسک پر شود. در سرویس managed از قابلیت رسمی provider استفاده کنید. خروجی را پیش از اشتراک از identifier، متن جستوجو و داده مشتری پاکسازی کنید.
فقط کندترین Query را انتخاب نکنید
| شاخص | چه میگوید؟ | دام رایج |
|---|---|---|
| زمان هر اجرا | latency یک نمونه | نادیده گرفتن فراوانی |
| مجموع زمان | هزینه کل الگوی Query | ترکیب endpointهای متفاوت |
| Rows examined | حجم کار موتور | تفسیر بدون plan |
| تعداد اجرا | الگوی N+1 یا hook پرتکرار | یک Query سریع و cacheable |
| Lock time | انتظار روی transaction | مقصر دانستن Query منتظر |
Execution Plan را بخوانید
EXPLAIN نشان میدهد optimizer چگونه جدولها و indexها را انتخاب میکند. روی Queryهای تغییردهنده، روش تحلیل نسخه دقیق را بررسی کنید و از اجرای تصادفی statement واقعی پرهیز کنید. plan را با schema و parameter مشابه production بگیرید؛ دیتای کوچک staging ممکن است plan دیگری تولید کند.
EXPLAIN SELECT ...;
نشانههایی مانند scan گسترده، temporary/filesort یا تخمین rows بالا نیازمند بررسیاند، اما هرکدام بهتنهایی حکم ساخت index نیستند. selectivity، ترتیب ستونها، sort، join و هزینه write باید با هم دیده شوند.
علتهای رایج Slow Query در وردپرس
- فیلترهای سنگین روی
postmetaیا ترکیب چند meta query. - جستوجوی wildcard با امکان استفاده محدود از index.
- صفحهبندی عمیق با offset بزرگ.
- Query داخل loop و الگوی N+1.
- autoload یا serialized option بسیار بزرگ.
- index ناکافی یا index زائد و آمار نامناسب.
- lock ناشی از transaction طولانی یا job همزمان.
- کمبود memory و temporary table روی disk.
راهحل را از کمریسک تا پیشرفته بچینید
۱. فراخوانی اضافی را حذف کنید
hook غیرضروری، Query داخل loop و درخواست تکراری را اصلاح کنید. گاهی cache در سطح مناسب از تغییر schema امنتر است، به شرط invalidation درست.
۲. دامنه داده را محدود کنید
ستون و تعداد رکورد لازم را بخوانید، pagination مناسب بسازید و گزارش سنگین را از request تعاملی جدا کنید. limit ظاهری همیشه هزینه sort یا join قبل از limit را کم نمیکند؛ plan را بسنجید.
۳. مدل داده یا Query را اصلاح کنید
دادهای که نیاز به فیلتر و مرتبسازی مداوم دارد شاید در serialized option یا meta جای مناسبی نداشته باشد. تغییر مدل نیازمند migration، سازگاری افزونه و rollback است.
۴. Index هدفمند بسازید
index باید از Query واقعی و plan بیاید، روی clone با حجم مشابه آزمایش شود و اثر insert/update و فضای disk سنجیده شود. تغییر جدول بزرگ ممکن است lock یا rebuild ایجاد کند؛ پنجره نگهداری و ابزار نسخه دقیق لازم است.
Object Cache چه زمانی کمک میکند؟
برای نتیجه تکراری با invalidation قابلاعتماد مفید است، اما Query یکتای هر کاربر یا جستوجو hit کمی دارد. cache کردن پاسخ اشتباه در قیمت، سطح دسترسی یا سبد خطرناک است. hit rate، memory و eviction را کنار latency بسنجید و cache را جای اصلاح Query بحرانی قرار ندهید.
برنامه آزمون پس از اصلاح
- همان سناریو و dataset قبل از تغییر
- cache سرد و گرم بهصورت جدا
- p50 و tail latency، نه یک درخواست
- rows examined و تعداد اجرا
- CPU، I/O، lock و connection
- صحت نتیجه، pagination و دسترسی
- هزینه write و jobهای پسزمینه
اشتباههای رایج
- فعال گذاشتن debug/profiler روی production عمومی
- انتشار slow log بدون حذف داده حساس
- افزودن index برای هر ستون
- اجرای Query نمونه با داده متفاوت
- پاک کردن جدول برای سریع شدن گزارش
- restart دیتابیس و از دست دادن شواهد
- بهینهسازی میانگین و نادیده گرفتن checkout
ارتباط با اندازه دیتابیس
اگر log نشان میدهد نگهداری و جدولهای متورم مؤثرند، بهینهسازی امن دیتابیس بزرگ وردپرس را اجرا کنید. اگر Queryها هنگام bootstrap به options مربوطاند، اندازه و autoload جدول wp_options را جدا تحلیل کنید.
چه زمانی کمک تخصصی لازم است؟
وقتی کندی فقط زیر بار رخ میدهد، Query با سفارش و پرداخت درگیر است یا تغییر index روی جدول بزرگ ریسک lock دارد، آزمون مستقیم روی production مناسب نیست. سرویس افزایش سرعت وردپرس میتواند trace اپلیکیشن، slow log و plan دیتابیس را در یک timeline بررسی کند.
پرسشهای متداول
چند Query برای یک صفحه زیاد است؟
عدد ثابت وجود ندارد؛ هزینه، تکرار، cacheability و latency دیتابیس مهمتر است.
آیا Query Monitor سایت را کند میکند؟
profiling سربار دارد؛ برای staging مناسبتر است و در production باید محدود، کوتاهمدت و کنترلشده باشد.
آیا هر Query بدون index کند است؟
خیر. جدول کوچک یا scan هدفمند ممکن است ارزان باشد. plan و workload واقعی تعیینکنندهاند.