Query Monitor (کویری مانیتور) یک افزونه رایگان و متن‌باز برای وردپرس است که به‌جای حدس‌زدن درباره علت کندی سایت، داده‌های واقعی از سطح Runtime را در اختیار می‌گذارد: کوئری‌های SQL (Structured Query Language)، هوک‌های وردپرس، تماس‌های HTTP API، بارگذاری اسکریپت‌ها و استایل‌ها، خطاهای PHP (Hypertext Preprocessor)، و زمان پردازش هر درخواست. برخلاف ابزارهایی مثل New Relic که در سطح سرور و با Instrumentation عمیق‌تر کار می‌کنند، Query Monitor در سطح افزونه باقی می‌ماند، اما همین محدودیت آن را به ابزار ایده‌آل محیط توسعه و Staging تبدیل می‌کند. پروفایلینگ حرفه‌ای با Query Monitor نیازمند روش‌شناسی مشخص است: تعریف Symptom، جداسازی گلوگاه، و تأیید رفع مشکل با اندازه‌گیری مجدد. این مقاله این روش‌شناسی را از نصب تا تحلیل پیشرفته کوئری‌های کند پوشش می‌دهد.

در یک پروژه فروشگاهی، صفحه Checkout (صفحه پرداخت) از ۱.۸ ثانیه به ۶.۳ ثانیه رسیده بود. هیچ افزونه جدیدی نصب نشده بود و هاست هم تغییر نکرده بود. Query Monitor در کمتر از پنج دقیقه نشان داد یک کوئری SELECT SQL_CALC_FOUND_ROWS روی جدول wp_postmeta، بدون Index (ایندکس)، ۴.۱ ثانیه طول می‌کشد. آن کوئری از یک افزونه گزارش‌گیری می‌آمد که در Hook woocommerce_checkout_init اجرا می‌شد. این نوع کشف، دقیقاً همان چیزی است که Query Monitor برای آن ساخته شده است.

Query Monitor چیست و چه تفاوتی با سایر ابزارها دارد؟

Query Monitor که توسط John Blackbourn توسعه یافته، در مخزن رسمی وردپرس به‌صورت رایگان در دسترس است و روی بیش از ۲۰۰,۰۰۰ نصب فعال گزارش شده است. این افزونه با استفاده از Hookهای بومی وردپرس مثل query، get_num_queries، و http_api_debug داده‌ها را جمع‌آوری می‌کند و در یک نوار (Toolbar) در پایین صفحه نمایش می‌دهد. برخلاف ابزارهای سطح سرور، Query Monitor هیچ Extension بومی نصب نمی‌کند و تمام اطلاعات را از لایه PHP وردپرس استخراج می‌کند.

تفاوت اصلی Query Monitor با ابزارهایی مثل New Relic این است که Query Monitor به شما می‌گوید «چه اتفاقی در این درخواست افتاده»، در حالی که New Relic می‌گوید «چه اتفاقی در این سیستم در طول زمان افتاده». اگر با پروفایلینگ وردپرس با New Relic آشنا باشید، می‌دانید که آن ابزار برای مانیتورینگ پیوسته محیط Production ساخته شده؛ Query Monitor برای دیباگ لحظه‌ای در محیط توسعه و Staging.

نکته مهم این است که Query Monitor نه فقط یک ابزار «نمایش تعداد کوئری» است، بلکه یک پلتفرم جامع Observability (مشاهده‌پذیری) در سطح وردپرس است. این افزونه ۱۳ پنل (Panel) مختلف دارد که هر کدام یک لایه از پشته اجرایی وردپرس را پوشش می‌دهد: Queries، Hooks & Actions، HTTP API Calls، Scripts & Styles، Languages، Admin Screen، Capability Checks، Environment، Rewrite Rules، Block Editor Blocks، Conditional Tags، Transients، و Debugging. پوشش این حجم از داده‌ها در یک افزونه رایگان، آن را به یک ضرورت تبدیل می‌کند.

«Query Monitor به شما نشان می‌دهد که چه چیزی در پشت صحنه وردپرس می‌گذرد — بدون اینکه نیاز به دسترسی root یا Instrumentation سطح سرور داشته باشید.»

از منظر معماری، Query Monitor با استفاده از مکانیزم Object Cache وردپرس و Hookهای بومی کار می‌کند. برای مثال، برای ردیابی کوئری‌ها، از فیلتر query و پارامتر SAVEQUERIES استفاده می‌کند. برای ردیابی تماس‌های HTTP، Hook http_api_debug را می‌گیرد. برای هوک‌ها، از ترکیب all و pre_do_action و do_action استفاده می‌کند. این رویکرد غیرتهاجمی باعث می‌شود که Query Monitor تقریباً هیچ Overhead (سرباری) در سطح سرور نداشته باشد و فقط در هنگام فعال بودن، داده‌ها را جمع کند.

نصب، فعال‌سازی و تنظیمات اولیه

نصب Query Monitor از طریق مخزن رسمی وردپرس انجام می‌شود. پس از نصب و فعال‌سازی، نیازی به تنظیمات پیچیده نیست؛ اما برای بهره‌برداری کامل، چند تنظیم کلیدی وجود دارد که باید فعال شوند:

اولین تنظیم مهم، فعال‌سازی SAVEQUERIES در فایل wp-config.php است. بدون این ثابت (Constant)، Query Monitor نمی‌تواند کوئری‌ها را ردیابی کند:

define( 'SAVEQUERIES', true );
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );

توجه کنید که WP_DEBUG_DISPLAY باید روی false بماند تا خطاهای PHP در بالای صفحه به‌صورت زشت و بی‌ربط نمایش داده نشوند. خطاها در فایل wp-content/debug.log ثبت می‌شوند و Query Monitor آن‌ها را در پنل Debugging نمایش می‌دهد. اگر با فعال‌سازی حالت Debug وردپرس آشنایی ندارید، مطالعه آن می‌تواند در این مرحله کمک‌کننده باشد.

دومین تنظیم، انتخاب سطح دسترسی (Capability) برای مشاهده Query Monitor است. به‌صورت پیش‌فرض، فقط کاربران با نقش administrator می‌توانند نوار Query Monitor را ببینند. اگر می‌خواهید آن را برای نقش‌های دیگر فعال کنید، می‌توانید از فیلتر qm_user_capability استفاده کنید:

add_filter( 'qm_user_capability', function() {
    return 'edit_posts';
} );

سومین تنظیم که در پروژه‌های واقعی حیاتی است، فعال‌سازی پنل Queries by Component است. این پنل به‌صورت پیش‌فرض غیرفعال است و باید از تنظیمات Query Monitor فعال شود. وقتی فعال باشد، نشان می‌دهد هر کوئری از کدام Component (هسته وردپرس، کدام افزونه، یا کدام قالب) آمده است. این ویژگی، تفاوت بین «کوئری کند پیدا کردن» و «پیدا کردن کدی که کوئری کند را نوشته» است.

چهارمین نکته: Query Monitor باید فقط در محیط Staging یا Development فعال باشد. اگر آن را در Production فعال بگذارید، Overhead آن می‌تواند به ۲۰ تا ۳۰ درصد برسد. این Overhead از دو منبع می‌آید: ذخیره تمام کوئری‌ها در حافظه، و جمع‌آوری داده‌های Hookها. Query Monitor خودش این هشدار را در پنل Environment نشان می‌دهد. اگر روی سرور پرترافیک هستید و نیاز به مانیتورینگ Production دارید، باید به سمت ابزارهایی مثل مانیتورینگ سرور با ابزارهای سطح زیرساخت بروید.

داشبورد Query Monitor: نقشه راه پروفایلینگ

وقتی Query Monitor فعال می‌شود، یک دکمه با عنوان «Query Monitor» در نوار مدیریت (Admin Bar) ظاهر می‌شود. با کلیک روی آن، یک منوی کشویی (Dropdown) با بیش از ۱۳ پنل باز می‌شود. هر پنل یک لایه از پشته اجرایی وردپرس را پوشش می‌دهد. در بالای این منو، چهار عدد کلیدی نمایش داده می‌شوند:

متریک توضیح مقدار هدف
Total Page Generation Time زمان کل تولید صفحه از ابتدای درخواست PHP تا پایان زیر ۵۰۰ms برای سایت معمولی
Peak Memory Usage حداکثر حافظه مصرفی PHP در طول پردازش زیر ۱۲۸MB برای اکثر سایت‌ها
Database Queries تعداد کوئری‌های SQL اجراشده در این درخواست زیر ۵۰ کوئری برای صفحه معمولی
Database Query Time مجموع زمان صرف‌شده در کوئری‌های SQL زیر ۲۰۰ms برای صفحه معمولی

این چهار عدد، نقطه شروع پروفایلینگ هستند. اگر Database Query Time بالای ۳۰٪ کل زمان تولید صفحه باشد، یعنی دیتابیس گلوگاه اصلی است. اگر Peak Memory Usage بالای ۲۵۶MB باشد، یعنی یک افزونه یا اسکریپت حافظه را می‌بلعد. اگر تعداد کوئری‌ها بالای ۱۰۰ باشد، یعنی معماری سایت مشکل دارد و باید کوئری‌های وردپرس با کدنویسی بهینه شوند.

«چهار عدد بالای منوی Query Monitor، شبیه علائم حیاتی بیمار در بخش مراقبت‌های ویژه است: فشار خون، ضربان قلب، تعداد نفس و دمای بدن. اگر هر کدام خارج از محدوده طبیعی باشد، باید عمیق‌تر کاوش کنید.»

علاوه بر این چهار عدد، Query Monitor نشان می‌دهد که آیا Object Cache (کش آبجکت) فعال است یا خیر، چه تعداد تماس HTTP انجام شده، و آیا خطای PHP ثبت شده است. این اطلاعات در یک نگاه، تصویر کاملی از سلامت درخواست ارائه می‌دهد. اگر سایت شما از Redis یا Memcached استفاده می‌کند، Query Monitor نشان می‌دهد که Object Cache فعال است و چه تعداد از کوئری‌ها از کش خوانده شده‌اند — نه از دیتابیس. این تفکیک در بهینه‌سازی حرفه‌ای حیاتی است.

تحلیل کوئری‌های SQL و شناسایی گلوگاه دیتابیس

پنل Queries پرکاربردترین بخش Query Monitor است. این پنل تمام کوئری‌های SQL اجراشده در طول یک درخواست را با جزئیات کامل نمایش می‌دهد: زمان اجرا، کوئری، Call Stack (پشته فراخوانی)، و کامپوننت صادرکننده. برای هر کوئری، چهار ستون اصلی وجود دارد:

  • Time: مدت اجرای کوئری به میلی‌ثانیه
  • Query: متن کامل کوئری SQL (با کوتاه‌سازی خودکار کوئری‌های طولانی)
  • Caller: تابع یا فایلی که کوئری را اجرا کرده
  • Component: افزونه، قالب، یا هسته وردپرس که مسئول کوئری است

اولین کاری که در تحلیل کوئری‌ها باید انجام دهید، مرتب‌سازی بر اساس ستون Time است. با کلیک روی سرستون، کوئری‌ها از کندترین به سریع‌ترین مرتب می‌شوند. به‌طور تجربی، هر کوئری بالای ۱۰۰ms باید بررسی شود و هر کوئری بالای ۵۰۰ms یک گلوگاه جدی است. اگر کوئری روی جدول wp_postmeta یا wp_options اجرا می‌شود و کند است، احتمالاً Index مناسب ندارد.

ستون Component یکی از قدرتمندترین ویژگی‌های Query Monitor است. اگر این ستون را فعال کنید، می‌بینید که مثلاً ۴۵ کوئری از هسته وردپرس، ۳۰ کوئری از یک افزونه فروشگاهی، و ۱۵ کوئری از یک افزونه سئو آمده است. این تفکیک به شما می‌گوید کدام افزونه مسئول فشار روی دیتابیس است. اگر با تأثیر افزونه‌های وردپرس بر سرعت سایت آشنا باشید، می‌دانید که یک افزونه به‌ظاهر سبک می‌تواند ده‌ها کوئری سنگین تولید کند.

تشخیص کوئری‌های تکراری (Duplicate Queries)

Query Monitor کوئری‌های تکراری را با برچسب «Duplicate» علامت‌گذاری می‌کند. اگر یک کوئری مشابه ده بار اجرا شود، این یک الگوی ضدالگو (Anti-Pattern) است. دو دلیل عمده برای کوئری‌های تکراری وجود دارد:

اول، عدم استفاده از Object Cache. اگر یک افزونه به‌جای استفاده از get_option() که خودش از کش وردپرس استفاده می‌کند، مستقیماً $wpdb->get_var() را صدا بزند، هر بار کوئری به دیتابیس می‌رود. دوم، حلقه‌های نادرست (N+1 Query Problem). اگر کدی در یک حلقه foreach روی هزاران رکورد، به‌ازای هر رکورد یک کوئری اجرا کند، نتیجه یک فاجعه عملکردی است. در Query Monitor، این الگو خودش را به‌صورت «۱۰۰ کوئری مشابه با اختلاف فقط در یک پارامتر» نشان می‌دهد.

راه‌حل N+1 Query Problem معمولاً یکی از این سه است: استفاده از WP_Query با post__in، استفاده از update_post_meta_cache() برای پرکردن کش متادیتا، یا استفاده از get_posts() با پارامترهای مناسب. اگر می‌خواهید درک عمیق‌تری از این تکنیک‌ها داشته باشید، بهینه‌سازی پیشرفته دیتابیس وردپرس مرجع خوبی است.

تحلیل Call Stack کوئری‌ها

یکی از ویژگی‌های کمتر شناخته‌شده اما بسیار قدرتمند Query Monitor، نمایش Call Stack برای هر کوئری است. با کلیک روی فلش کنار هر کوئری، یک زنجیره از توابع نمایش داده می‌شود که به کوئری ختم می‌شود. این Call Stack از سطح wpdb::query() شروع می‌شود و تا کدی که واقعاً کوئری را صدا زده بالا می‌رود. برای مثال، ممکن است Call Stack نشان دهد که کوئری از WP_Query::get_posts() آمده، که خودش توسط wp_nav_menu() صدا زده شده، که در قالب در Hook wp_nav_menu_args فراخوانی شده است.

این Call Stack زمانی حیاتی است که Component به‌تنهایی کافی نیست. مثلاً اگر یک افزونه از WP_Query استفاده می‌کند، Component نشان می‌دهد «WordPress Core» چون WP_Query بخشی از هسته است. اما Call Stack نشان می‌دهد که این WP_Query توسط کدام فایل افزونه ایجاد شده. این تفکیک، در پروژه‌های با ده‌ها افزونه، تفاوت بین حل مشکل در پنج دقیقه و پنج ساعت است.

بررسی Hooks و Actions: کدام افزونه زمان می‌بلعد؟

پنل Hooks & Actions در Query Monitor، تمام Hookهای اجراشده در طول یک درخواست را نمایش می‌دهد. برای هر Hook، چهار ستون وجود دارد: نام Hook، نوع (Action یا Filter)، Callbackهای ثبت‌شده، و زمان اجرای هر Callback. این پنل به شما می‌گوید که در یک درخواست، کدام Hook بیشترین زمان را می‌برد و کدام افزونه مسئول آن است.

اولین مشاهده در این پنل معمولاً شوکه‌کننده است: یک Hook مثل init می‌تواند ۵۰ تا ۱۰۰ Callback داشته باشد که از ۲۰ افزونه مختلف می‌آید. اگر زمان کل این Hook بالای ۲۰۰ms باشد، یک مشکل جدی وجود دارد. اما نکته مهم‌تر این است که Query Monitor فقط زمان کل Hook را نشان نمی‌دهد؛ زمان هر Callback را نیز تفکیک می‌کند. این یعنی می‌توانید ببینید که در Hook init، یک Callback خاص از یک افزونه، ۱۵۰ms از آن ۲۰۰ms را می‌بلعد.

«Hookها ستون فقرات وردپرس هستند، اما در پروژه‌های با افزونه‌های زیاد، به گورستان عملکرد تبدیل می‌شوند. Query Monitor قبرکن است.»

در پنل Hooks & Actions، Query Monitor سه فیلتر مهم ارائه می‌دهد: All، Actions، و Filters. همچنین می‌توانید بر اساس Component فیلتر کنید. این فیلترها زمانی حیاتی می‌شوند که بخواهید بدانید یک افزونه خاص، در کدام Hookها ثبت شده و چقدر زمان می‌برد. برای مثال، اگر یک افزونه کند دارید، می‌توانید آن را فیلتر کنید و ببینید در کدام Hookها فعال است. اگر با دیباگ کردن Action و Filter در وردپرس آشنا باشید، این اطلاعات برای شما طلا خواهد بود.

تشخیص Hookهای با Priority نامناسب

هر Hook در وردپرس یک Priority (اولویت) دارد. Callbackها با Priority پایین‌تر (مثلاً ۱) زودتر اجرا می‌شوند و Callbackهای با Priority بالاتر (مثلاً ۹۹۹) دیرتر. Query Monitor این Priority را نیز نمایش می‌دهد. اگر یک افزونه در Hook init با Priority PHP_INT_MAX ثبت شده باشد، یعنی عمداً می‌خواهد آخرین Callback باشد. این کار معمولاً برای اطمینان از اینکه تنظیمات دیگران اعمال شده، انجام می‌شود، اما اگر آن Callback کند باشد، تمام درخواست را کند می‌کند.

نکته ظریف‌تر این است که Query Monitor زمان هر Callback را از لحظه شروع تا پایان اجرای آن اندازه‌گیری می‌کند. اگر یک Callback در وسط اجرا، یک Hook دیگر را do_action() کند، زمان آن Hook درونی نیز در محاسبه زمان Callback بیرونی لحاظ می‌شود. این یعنی ممکن است یک Callback به‌ظاهر کند، اما در واقع کندی از Hook درونی آن بیاید. Call Stack در Query Monitor این زنجیره را نشان می‌دهد.

Hooks در قلب Query Monitor

پنل Hooks در Query Monitor خودش از یک Hook بومی وردپرس استفاده می‌کند: all. این Hook از نسخه ۴.۷ وردپرس اضافه شده و به‌ازای هر Hook اجراشده، صدا زده می‌شود. Query Monitor از این Hook برای شمارش و ردیابی استفاده می‌کند. همین موضوع نشان می‌دهد که وردپرس در سطح هسته، Observability را جدی گرفته است.

تماس‌های HTTP API: قاتل خاموش سرعت

یکی از پنهان‌ترین گلوگاه‌های سرعت در وردپرس، تماس‌های HTTP API خارجی است. وقتی یک افزونه با یک سرویس بیرونی (مثل درگاه پرداخت، سرویس ایمیل، API احراز هویت، یا سرویس ترجمه) صحبت می‌کند، یک تماس HTTP انجام می‌شود که می‌تواند بین ۵۰ms تا چند ثانیه طول بکشد. اگر این تماس در مسیر Critical Rendering (رندر حیاتی) باشد و کش نشود، کل درخواست را کند می‌کند.

پنل HTTP API Calls در Query Monitor، تمام این تماس‌ها را نشان می‌دهد: URL، متد (GET, POST)، کد وضعیت، زمان اجرا، و کامپوننت صادرکننده. این پنل معمولاً تماس‌هایی را فاش می‌کند که هیچ‌کس از وجودشان خبر ندارد. برای مثال، یک افزونه امنیتی ممکن است در هر بارگذاری صفحه، یک درخواست به سرور خودش بزند تا بررسی کند آیا نسخه جدیدی منتشر شده. اگر این سرور کند باشد یا در دسترس نباشد، کل سایت کند می‌شود.

در پنل HTTP API Calls، به دنبال الگوهای زیر باشید:

  • تماس‌هایی با زمان بالای ۵۰۰ms
  • تماس‌هایی که در هر درخواست تکرار می‌شوند (بدون کش)
  • تماس‌هایی به دامنه‌های ناشناس یا سرویس‌های خارجی
  • تماس‌هایی با کد وضعیت 4xx یا 5xx که باعث Retry (تلاش مجدد) می‌شوند

اگر تماس HTTP کند پیدا کردید، سه راه حل وجود دارد: اول، فعال کردن Transient API (کش موقت) برای ذخیره نتیجه؛ دوم، استفاده از wp_remote_get() با timeout کوتاه و مدیریت خطای مناسب؛ سوم، حذف یا جایگزینی افزونه‌ای که این تماس را ایجاد می‌کند. اگر با بهینه‌سازی دیتابیس وردپرس آشنا هستید، می‌دانید که Transient API نتایج را در جدول wp_options ذخیره می‌کند و بازیابی آن تقریباً رایگان است.

بارگذاری اسکریپت‌ها و استایل‌ها

پنل Scripts & Styles در Query Monitor، تمام فایل‌های JavaScript (JS) و CSS (Cascading Style Sheets) بارگذاری‌شده در صفحه را با جزئیات نمایش می‌دهد: Handle، وابستگی‌ها (Dependencies)، Src (آدرس فایل)، و کامپوننت صادرکننده. این پنل به شما می‌گوید که چند فایل JS و CSS در صفحه بارگذاری می‌شود و هر کدام از کجا می‌آید.

در سایت‌های وردپرسی با افزونه‌های زیاد، تعداد فایل‌های JS و CSS می‌تواند به ۵۰ تا ۱۰۰ عدد برسد. هر فایل یک درخواست HTTP جداگانه است و مرورگر باید آن را دانلود و Parse (تجزیه) کند. Query Monitor این تعداد را به‌صورت شفاف نمایش می‌دهد و به شما می‌گوید کدام فایل از کدام افزونه می‌آید. اگر تعداد فایل‌ها بالای ۳۰ باشد، باید به فکر ادغام (Concatenation) یا استفاده از یک ابزار کش وردپرس باشید که فایل‌ها را ادغام و Minify (فشرده) کند.

نکته مهم در این پنل، مشاهده فایل‌هایی است که در صفحه‌ای بارگذاری می‌شوند که به آن‌ها نیازی نیست. برای مثال، ممکن است یک افزونه فرم‌ساز، اسکریپت‌هایش را در تمام صفحات سایت بارگذاری کند، حتی در صفحاتی که هیچ فرمی وجود ندارد. این الگو، یکی از شایع‌ترین دلایل کندی سایت‌های وردپرسی است. Query Monitor این مشکل را بلافاصله فاش می‌کند و می‌توانید با استفاده از wp_dequeue_script() یا wp_dequeue_style()، آن‌ها را در صفحات غیرضروری حذف کنید.

گردش کار پروفایلینگ: از Symptom تا Root Cause

پروفایلینگ با Query Monitor بدون یک روش‌شناسی مشخص، فقط به انبوهی از داده منجر می‌شود. روش‌شناسی‌ای که در پروژه‌های واقعی جواب داده، شامل پنج گام است:

گام اول: تعریف Symptom به‌صورت دقیق

«سایت کند است» یک Symptom نیست. Symptom دقیق این است: «صفحه محصول فلان دسته‌بندی، در حالت لاگین، ۴.۲ ثانیه طول می‌کشد، در حالی که در حالت مهمان ۱.۱ ثانیه است.» این سطح از دقت، نقطه شروع پروفایلینگ است. اگر با عیب‌یابی مشکل سرعت سایت آشنا باشید، می‌دانید که تفکیک شرایط (لاگین/مهمان، دسکتاپ/موبایل، جغرافیا) کلید یافتن ریشه است.

گام دوم: اندازه‌گیری Baseline

قبل از تغییر هر چیزی، باید Baseline (خط پایه) داشته باشید. چهار عدد بالای منوی Query Monitor — Time، Memory، Queries، Query Time — را ثبت کنید. اگر این اعداد را نداشته باشید، بعد از تغییرات نمی‌توانید بفهمید که بهبود داشته‌اید یا بدتر شده است.

گام سوم: جداسازی لایه گلوگاه

با نگاه به چهار عدد، لایه گلوگاه را مشخص کنید:

الگوی مشاهده لایه گلوگاه پنل هدف
Query Time بالای ۳۰٪ کل زمان دیتابیس Queries
Peak Memory بالای ۲۵۶MB PHP / افزونه سنگین Hooks & Actions
Query Count بالای ۱۰۰ معماری کوئری / N+1 Queries (Duplicate)
Time بالا اما Queries و Query Time پایین HTTP API یا بارگذاری فایل HTTP API Calls

گام چهارم: Drill-down به Component

بعد از شناسایی لایه، در پنل مربوطه به دنبال Component بگردید. اگر Query Time بالا است، در پنل Queries به دنبال کوئری‌های بالای ۱۰۰ms بگردید و ببینید از کدام Component می‌آیند. اگر Memory بالا است، در پنل Hooks & Actions به دنبال Callbackهای سنگین بگردید. اگر Time بالا اما Queries پایین است، در پنل HTTP API Calls به دنبال تماس‌های کند بگردید.

گام پنجم: تأیید و اندازه‌گیری مجدد

بعد از رفع مشکل، همان صفحه را دوباره بارگذاری کنید و چهار عدد را با Baseline مقایسه کنید. اگر بهبود حاصل نشد، یعنی گلوگاه در لایه دیگری است و باید گام سوم را تکرار کنید. این چرخه «اندازه‌گیری → تغییر → اندازه‌گیری» تا رسیدن به عملکرد هدف ادامه می‌یابد.

«پروفایلینگ بدون Baseline، مثل دویدن در تاریکی است. Query Monitor چراغ‌قوه است، اما شما باید بدانید به کدام سمت می‌روید.»

در پروژه‌های بزرگ، این گردش کار می‌تواند چندین ساعت طول بکشد. اما نکته کلیدی این است که Query Monitor به شما اجازه می‌دهد در هر لحظه بدانید کجای مسیر هستید و کدام لایه را باید بررسی کنید. اگر می‌خواهید این گردش کار را برای افزایش سرعت کلی سایت به کار ببرید، افزایش گام‌به‌گام سرعت وردپرس یک نقشه راه عملی ارائه می‌دهد.

Query Monitor در مقابل New Relic، Blackfire و Debug Bar

Query Monitor بخشی از یک اکوسیستم ابزارهای پروفایلینگ است و انتخاب بین آن‌ها به محیط و هدف بستگی دارد. جدول زیر تفاوت‌های کلیدی را نشان می‌دهد:

ویژگی Query Monitor New Relic Blackfire Debug Bar
محیط هدف Development / Staging Production Development Development
Overhead متوسط تا بالا پایین (با threshold) نزدیک به صفر بالا
ردیابی Hook جامع بومی محدود پایه
ردیابی HTTP API بله بله خیر خیر
Flame Graph خیر محدود بله (دقیق) خیر
هزینه رایگان ۱۰۰GB رایگان پولی رایگان

ترکیب متداول در تیم‌های حرفه‌ای این است: Query Monitor برای دیباگ لحظه‌ای در Staging، Blackfire برای پروفایلینگ عمیق یک تابع خاص، و New Relic برای مانیتورینگ پیوسته Production. Debug Bar امروزه تا حد زیادی با Query Monitor جایگزین شده، چون Query Monitor داده‌های بیشتری با رابط کاربری بهتری ارائه می‌دهد.

نکته‌ای که در مقایسه‌ها اغلب نادیده گرفته می‌شود این است: Query Monitor در سطح PHP کار می‌کند و به همین دلیل، محدود به چرخه درخواست وردپرس است. ابزارهایی مثل New Relic که در سطح سرور کار می‌کنند، می‌توانند چیزهایی مثل زمان انتظار در صف Nginx، یا کندی DNS را نیز ببینند. بنابراین، اگر مشکل شما در لایه‌ای خارج از PHP است، Query Monitor کمکی نمی‌کند. اما اگر مشکل در PHP، دیتابیس، یا تماس‌های HTTP درون وردپرس است، Query Monitor دقیق‌ترین ابزار موجود است.

اشتباهات رایج در استفاده از Query Monitor

اشتباه اول: فعال گذاشتن Query Monitor در Production. Query Monitor در Production می‌تواند Overhead ۲۰ تا ۳۰ درصدی ایجاد کند و خودش باعث کندی شود. اگر روی سایت پرترافیک هستید، باید آن را غیرفعال کنید و از ابزارهای سطح سرور استفاده کنید.

اشتباه دوم: تفسیر نادرست تعداد کوئری‌ها. تعداد کوئری بالا لزوماً به معنای مشکل نیست. یک صفحه فروشگاهی پیچیده به‌طور طبیعی ۵۰ تا ۸۰ کوئری دارد. نکته مهم، زمان کل کوئری‌ها و وجود کوئری‌های تکراری است، نه صرفاً تعداد. اگر با تعداد افزونه‌های وردپرس و تأثیر آن‌ها آشنا باشید، می‌دانید که تعداد کوئری‌ها به تعداد افزونه‌ها بستگی مستقیم ندارد.

اشتباه سوم: نادیده گرفتن پنل HTTP API Calls. بسیاری از کاربران فقط به پنل Queries نگاه می‌کنند و پنل HTTP API را باز نمی‌کنند. در حالی که در سایت‌های مدرن که با سرویس‌های بیرونی ادغام شده‌اند، تماس‌های HTTP اغلب گلوگاه اصلی هستند.

اشتباه چهارم: فعال نکردن SAVEQUERIES و انتظار دیدن کوئری‌ها. اگر این ثابت در wp-config.php تعریف نشده باشد، Query Monitor نمی‌تواند کوئری‌ها را ردیابی کند و پیام هشدار نشان می‌دهد. این یکی از رایج‌ترین اشتباهات مبتدیان است.

اشتباه پنجم: استفاده همزمان Query Monitor و افزونه‌های مشابه مثل Debug Bar یا Query Monitor Extended. این افزونه‌ها با هم تداخل می‌کنند و ممکن است داده‌های یکدیگر را تحریف کنند. در هر زمان فقط یک ابزار پروفایلینگ باید فعال باشد.

اشتباه ششم: نادیده گرفتن Object Cache. اگر Object Cache فعال نباشد، Query Monitor تعداد کوئری‌های بالایی نشان می‌دهد که طبیعی است. قبل از هر بهینه‌سازی، باید Object Cache (Redis یا Memcached) فعال باشد. اگر با پاک‌سازی اسپم و ترنزینت‌های وردپرس آشنا باشید، می‌دانید که ترنزینت‌ها نیز بخشی از استراتژی کش هستند.

پرسش‌های پرتکرار درباره Query Monitor

آیا Query Monitor روی سرعت سایت تأثیر منفی می‌گذارد؟

بله، Query Monitor در حالت فعال Overhead قابل‌توجهی دارد. این Overhead از دو منبع می‌آید: ذخیره تمام کوئری‌ها در حافظه PHP، و جمع‌آوری داده‌های Hookها. میزان Overhead بستگی به تعداد کوئری‌ها و Hookها دارد و می‌تواند از ۵٪ تا ۳۰٪ متغیر باشد. به همین دلیل، Query Monitor باید فقط در محیط Development یا Staging فعال باشد و در Production غیرفعال شود.

چگونه Query Monitor را روی سایت Production نصب کنم بدون اینکه سایت کند شود؟

روش توصیه‌شده این است که Query Monitor را با یک شرط فعال کنید که فقط برای IP شما یا یک پارامتر خاص در URL فعال شود. برای این کار می‌توانید از فیلتر qm_user_capability یا شرط if ( $_SERVER['REMOTE_ADDR'] === 'YOUR_IP' ) استفاده کنید. این روش به شما اجازه می‌دهد مشکل واقعی Production را ببینید بدون اینکه سایر کاربران کندی را تجربه کنند.

تفاوت Query Monitor و New Relic در پروفایلینگ وردپرس چیست؟

Query Monitor در سطح PHP وردپرس کار می‌کند و در محیط Development یا Staging استفاده می‌شود. New Relic در سطح سرور و با Instrumentation عمیق‌تر کار می‌کند و برای مانیتورینگ پیوسته Production طراحی شده است. Query Monitor برای «چرا این صفحه خاص کند است» بهتر است؛ New Relic برای «چه زمانی سایت کند می‌شود و چرا» در طول زمان.

چگونه کوئری تکراری را در Query Monitor پیدا کنم؟

در پنل Queries، کوئری‌های تکراری با برچسب «Duplicate» مشخص می‌شوند. همچنین می‌توانید ستون Time را مرتب کنید و به دنبال کوئری‌هایی بگردید که متن یکسانی دارند اما فقط یک پارامتر آن‌ها متفاوت است. این الگو معمولاً نشانه N+1 Query Problem است. برای رفع آن، باید از post__in در WP_Query یا از update_post_meta_cache() استفاده کنید.

چرا Query Monitor تعداد کوئری‌های بالایی نشان می‌دهد اما سایت سریع است؟

تعداد کوئری‌ها به‌تنهایی معیار خوبی برای سرعت نیست. اگر کوئری‌ها از Object Cache (کش آبجکت) خوانده شوند، یا از Index مناسب استفاده کنند، حتی ۲۰۰ کوئری می‌تواند در کمتر از ۱۰۰ms اجرا شود. نکته مهم، مجموع زمان کوئری‌ها و وجود کوئری‌های کند است، نه تعداد آن‌ها. اگر سایت سریع است و Query Monitor تعداد بالایی نشان می‌دهد، احتمالاً Object Cache فعال است و کوئری‌ها از حافظه خوانده می‌شوند.

آیا Query Monitor با WooCommerce سازگار است؟

بله، Query Monitor به‌صورت بومی با WooCommerce کار می‌کند و کوئری‌های مربوط به محصولات، سفارش‌ها، و سبد خرید را در Component جداگانه نمایش می‌دهد. همچنین Hookهای WooCommerce مثل woocommerce_before_single_product و woocommerce_checkout_init در پنل Hooks & Actions قابل مشاهده هستند. این موضوع در عیب‌یابی مشکلاتی مثل کندی صفحه Checkout یا خطای پرداخت ووکامرس بسیار مفید است.

چگونه Query Monitor را برای Multisite پیکربندی کنم؟

Query Monitor روی Multisite به‌صورت پیش‌فرض کار می‌کند، اما باید آن را در سطح Network فعال کنید تا در تمام سایت‌های شبکه قابل دسترسی باشد. همچنین می‌توانید از فیلتر qm_user_capability برای کنترل دسترسی در هر سایت استفاده کنید. توجه داشته باشید که در Multisite، پنل Queries ممکن است کوئری‌های مربوط به سایت‌های دیگر را نیز نشان دهد، بنابراین باید با دقت تفکیک کنید.

نگاه نهایی به پروفایلینگ با Query Monitor

Query Monitor یک ابزار رایگان است که در عمل، ارزش آن با بسیاری از ابزارهای پولی برابری می‌کند. اما این ابزار تنها زمانی مؤثر است که با یک روش‌شناسی مشخص استفاده شود. پروفایلینگ بدون Baseline، بدون تعریف Symptom دقیق، و بدون جداسازی لایه گلوگاه، فقط به سرگیجه منجر می‌شود. تفاوت بین یک مهندس تازه‌کار و یک مهندس ارشد در استفاده از Query Monitor، نه در دانش پنل‌ها، بلکه در توانایی تفسیر داده‌ها و اتصال آن‌ها به کد واقعی است.

در نهایت، Query Monitor جایگزین ابزارهای سطح سرور نمی‌شود. ترکیب Query Monitor برای دیباگ لحظه‌ای، Blackfire برای پروفایلینگ عمیق، و New Relic برای مانیتورینگ پیوسته، یک استراتژی جامع Observability در وردپرس می‌سازد. اگر می‌خواهید در مورد بهینه‌سازی دیتابیس که اغلب گام بعدی بعد از پروفایلینگ است بیشتر بدانید، بهینه‌سازی ایمن دیتابیس وردپرس و خطاهای رایج وردپرس و رفع آن‌ها می‌توانند مکمل خوبی باشند.

نگاه مهندسی سطح بالا

از منظر معماری نرم‌افزار، Query Monitor یک نمونه جالب از Self-Instrumentation در سطح Application است: به‌جای وابستگی به Agent خارجی، خود اپلیکیشن با استفاده از Hookهای بومی، Observability را تزریق می‌کند. این رویکرد مزایای روشنی دارد — عدم نیاز به دسترسی root، سادگی نصب، و یکپارچگی کامل با چرخه درخواست وردپرس — اما محدودیت‌هایی نیز دارد: Overhead درون PHP، عدم پوشش لایه‌های خارج از Application (مثل Nginx، PHP-FPM، یا DNS)، و ناتوانی در تشخیص مسائل سطح سیستم‌عامل. در معماری‌های مدرن، این رویکرد با استانداردهای باز مثل OpenTelemetry (OTel) تکامل یافته، جایی که Instrumentation در سطح Application با جمع‌آوری داده در سطح لبه (Edge) ترکیب می‌شود. Query Monitor به‌تنهایی این سطح را پوشش نمی‌دهد، اما به‌عنوان لایه اول تشخیص در محیط توسعه، جایگاه خود را حفظ کرده است.

اگر این مشکل را در یک پروژه واقعی تجربه کرده‌اید، برای علاقه‌مندی جالب است بدانید کدام بخش آن بیشترین زمان را از شما گرفت. تجربه خودتان را در دیدگاه‌ها بنویسید؛ به‌خصوص اگر راه‌حل دیگری پیدا کرده‌اید که می‌تواند برای خواننده بعدی مفید باشد. 🔍