← 返回首页

Query Monitor 调试实战

WordPressQuery Monitor性能优化数据库调试REST API

说出来有点丢人——我在 WordPress 圈子里混了这么久,Query Monitor 这个插件一直装着但从来没认真用过。直到上个月我的一个 WooCommerce 测试站(50K 产品)首页 TTFB 突然飙到 4.2 秒,wp-admin 后台打开任意页面都要 8 秒以上,我才不得不打开这个平时只看一眼就关掉的调试面板。

结果发现了一个我根本没想到的问题:一个"SEO 优化"插件在每次页面加载时偷偷跑了 47 条 SQL 查询,其中有 23 条是 SELECT * FROM wp_options WHERE autoload='yes'——全表扫描,每次 180ms。我把这个插件禁用后,TTFB 直接从 4.2 秒掉到 1.1 秒。

这次经历让我意识到 Query Monitor 不只是一个"看看有几个查询"的工具,它其实藏着很多能帮你定位根因的功能,但大部分人只用了它 10% 的能力。

Query Monitor 3.17.x 安装后的第一件事:关掉"只对管理员可见"

Query Monitor 默认只对 Administrator 角色可见,这在开发环境没问题,但在生产环境排查问题时很麻烦——你经常需要用一个Subscriber 账号复现前端性能问题,而这个角色看不到 Query Monitor 面板。

wp-config.php 里加一行就能解决:

define('QM_SHOW_ALL', true);

但要注意,这个常量在生产环境只应该在排查期间临时开启,排查完必须删掉。我有一次忘了删,结果一个作者角色的同事看到了满屏的 SQL 查询和 hook 信息,吓得以为网站被黑了。

另一个更有用的设置是禁用 Query Monitor 自身的性能开销——它默认会在每次页面加载时额外增加 2-5ms 的开销来收集数据,如果你在跑 benchmark 对比,这个开销会干扰结果:

define('QM_DISABLED', true);  // 完全禁用收集,但面板仍显示上次数据

隐藏功能一:Queries by Caller — 追踪"谁调了这条 SQL"

Query Monitor 的 "Queries" 面板默认按耗时排序所有 SQL 查询,但这只告诉你"哪条慢",不告诉你"谁让它慢的"。

点击面板右上角的 "Queries by Caller" 标签,它会把所有 SQL 查询按调用来源分组——比如 WooCommerce->get_products() 调了 35 条查询,theme_setup 调了 12 条,plugin_seo_optimizer->generate_meta() 调了 47 条。

这个视图让我发现了一个真实案例:一个"WooCommerce 产品比较"插件在每个产品页面加载时都会查询全部产品属性(wp_wc_product_attributes_lookup 表),即使当前页面根本没有比较功能。通过 Queries by Caller 我一眼就定位到了是 class-wc-product-compare.php:142 这个文件调的,然后用 remove_action('wp_enqueue_scripts', ...) 在不需要的页面禁用了它,单页查询数从 89 降到 42。

具体操作步骤:打开 Query Monitor → 点击 "Database Queries" → 切换到 "Queries by Caller" 标签 → 找到调用次数最多的 caller → 点击它可以看到完整调用栈(包括文件名和行号)。

隐藏功能二:Hooks & Actions — 发现插件打架的真正元凶

插件冲突是 WordPress 最让人头疼的问题之一,传统排查方法是逐个禁用插件然后看问题是否消失。但 Query Monitor 的 "Hooks & Actions" 面板提供了一个更聪明的方法。

这个面板会列出当前页面触发的所有 hooks,以及每个 hook 上挂载了多少个回调函数。如果某个 hook 上挂了 15 个以上的回调,你就要警惕了——特别是 wp_headwp_enqueue_scriptsinit 这三个 hook,它们是插件冲突的重灾区。

我遇到过一个真实案例:两个 SEO 插件(一个是 Rank Math,一个是某个 Schema 插件)同时在 wp_head hook 上输出 JSON-LD 结构化数据,导致 Google Search Console 报 "Duplicate field 'author'" 错误。在 Hooks & Actions 面板里找到 wp_head,看到两个回调函数都输出了