← Back to Home

Query Monitor Debugging实战

WordPressQuery MonitorPerformance OptimizationDatabase DebuggingREST API

I'm almost embarrassed to admit this — I've had Query Monitor installed for years but never really used it. That changed last month when a WooCommerce test site (50K products) suddenly hit 4.2s TTFB on the homepage, and wp-admin was taking 8+ seconds to load any page. I had no choice but to open that debug panel I'd been ignoring.

What I found was something I never expected: an "SEO optimization" plugin was secretly running 47 SQL queries on every page load, with 23 of them being SELECT * FROM wp_options WHERE autoload='yes' — full table scans, 180ms each. I disabled that plugin and TTFB dropped from 4.2s to 1.1s instantly.

That experience made me realize Query Monitor isn't just a "see how many queries you have" tool. It has hidden capabilities that most people never discover, but they can pinpoint root causes with surgical precision.

The First Thing After Installing Query Monitor 3.17.x: Disable Admin-Only Visibility

By default, Query Monitor is only visible to Administrator roles. This works fine in development, but when debugging production issues, you often need to reproduce problems with a Subscriber account — and that role can't see the panel.

Add this to wp-config.php:

define('QM_SHOW_ALL', true);

But only enable this temporarily during debugging sessions. I once forgot to remove it, and a colleague with Author role panicked after seeing a wall of SQL queries and hook information, thinking the site was hacked.

A more useful setting for benchmarking is disabling Query Monitor's own performance overhead — it adds 2-5ms per page load to collect data, which skews benchmark results:

define('QM_DISABLED', true);  // Disables data collection, but panel still shows last captured data

Hidden Feature #1: Queries by Caller — Track Down "Who Called This SQL"

The default "Queries" panel sorts all SQL queries by execution time, but that only tells you "which one is slow" — not "who made it slow."

Click the "Queries by Caller" tab in the top-right corner. It groups all SQL queries by their call source — for example, WooCommerce->get_products() ran 35 queries, theme_setup ran 12, and plugin_seo_optimizer->generate_meta() ran 47.

This view exposed a real issue for me: a "WooCommerce product comparison" plugin was querying all product attributes (wp_wc_product_attributes_lookup table) on every single product page load, even when the comparison feature wasn't being used. Through Queries by Caller, I pinpointed it to class-wc-product-compare.php:142 and used remove_action('wp_enqueue_scripts', ...) to disable it on unnecessary pages. Per-page query count dropped from 89 to 42.

Steps: Open Query Monitor → Click "Database Queries" → Switch to "Queries by Caller" tab → Find the caller with the highest query count → Click it to see the full call stack (including filename and line number).

Hidden Feature #2: Hooks & Actions — Find the Real Culprit Behind Plugin Conflicts

Plugin conflicts are one of WordPress's most frustrating problems. The traditional approach is disabling plugins one by one until the issue disappears. But Query Monitor's "Hooks & Actions" panel offers a smarter method.

This panel lists all hooks triggered on the current page, along with how many callback functions are attached to each hook. If a hook has 15+ callbacks, be cautious — especially wp_head, wp_enqueue_scripts, and init, which are the top conflict hotspots.

I encountered a real case: two SEO plugins (Rank Math and a Schema plugin) were both outputting JSON-LD structured data on the wp_head hook, causing Google Search Console to report "Duplicate field 'author'" errors. Finding wp_head in the Hooks & Actions panel immediately showed two callbacks both outputting