如果您不能按注释类型进行限制,则GET_COMMENT_COUNT()的意义何在?

时间:2014-01-22 作者:Jason

我们发现大型WooCommerce网站运行速度非常慢。在许多问题中,这一个让我挠头。

WooComemrce将订单注释存储在comments表中,为其提供“order\\u note”的注释类型,并立即批准。它们链接到订单,因此只能由店铺管理员看到。

现在,一个站点上的某些内容(尚未跟踪)正在执行此查询:

SELECT comment_approved, COUNT(*) AS total
FROM wp_comments
GROUP BY comment_approved
系统上有120k条评论,大多数是“order\\u note”类型,这在每次页面加载上都要花费大量的时间(最多500毫秒的查询时间),并且会影响服务器。这个问题的重点是什么?它获取comments表中所有行的计数,按审批状态分组。它统计注释、trackback、ping和order\\u注释。这有什么意义?我想不出在每一页上都做这样的查询有什么用。

wp中的get\\u comment\\u count()函数包括/comment。php将运行此查询。如果您传入post ID,那么它将对该post进行汇总。这很快。如果不传入post ID,那么它会计算整个表中的所有行,这很慢,而且我也没用。此函数不接受comment\\u类型,因此不能将查询限制为特定类型的注释。

当我跟踪这个查询的来源时,我想知道为什么WP会支持这样查询整个表。这是一种假设,即永远不会创建自定义注释类型,即注释表将永远不会用于codex中列出的三种注释类型之外的任何内容。是这样吗?WooCommerce是否完全滥用了这张桌子?

我不确定我在这里寻找的是什么样的答案,但我怀疑需要在某个地方提出问题(可能是在函数中的查询WHERE子句中添加comment\\u类型),因此,我想看看这个有问题的查询有什么想法或类似的经历。

更新:

确切查询:

SELECT comment_approved, COUNT( * ) AS num_comments
FROM wp_comments
GROUP BY comment_approved
这将持续运行300mS,并返回以下结果:

|评论|已批准| num |评论| num |------------------------0 | 1 | | 1 | 191370 | |后垃圾| 1 | |垃圾邮件| 29|

优化表格后没有差异。现在我注意到count别名为“num\\u comments”,而不是“total”,这意味着正在运行的是wp\\u count\\u comments(),而不是get\\u comment\\u count()。这意味着计数结果应该缓存在key comments-0下,但事实并非如此-查询是在每个页面上运行的。可能缓存正在清除页面上的其他位置?

但是,这样做还是没有用的。大多数“批准的”评论都是WooCommerce添加的order\\u注释。它们不是通常意义上的“评论”。

comment\\u approved列被编入索引(复合索引中的第一列),WP表示它的基数为7,即使查询只返回四个组。这大约需要1mS:

SELECT DISTINCT comment_approved
FROM wp_comments
因此,索引在那里工作,但当需要计数时,它会变慢,而这实际上只需要检查索引。

解释计划是:

选择\\u type=SIMPLEtable=wp\\u CommentType=indexpossible\\u keys=NULLkey=comment\\u approved\\u date\\u gmt(?)key\\u len=70ref=NULLrows=195885Extra=使用索引

也许这只是MySQL在优化方面非常糟糕的事情之一,比如sub-select,它从第一天起就非常糟糕。

1 个回复
SO网友:Otto

该查询在get_comment_count() 核心功能。这个wp_count_comments() 函数运行类似的查询,但它使用wp\\u缓存系统缓存生成的数据(因此不会在每个请求中运行该代码多次)。get_comment_count() 不使用缓存。

问题是,在我看来,这是一个完全有效的查询。它这样做是为了统计被审核、批准、垃圾等评论的数量。

现在,comment\\u approved是该表中的索引键,所以实际上,查询应该非常快。当我对该查询运行EXPLAIN时,MySQL告诉我这是一个简单的select,在comment_approved_date_gmt 钥匙

因此,无论如何,它都不是一个慢查询,注释类型也不会有任何影响。如果它对您来说很慢,那么您的注释表可能有问题。索引是否正确编制?尝试在表上运行优化。尽管如此,由于该查询只应该真正命中索引,而不一定命中表,我认为这无关紧要。

查询的速度不取决于要查询的记录数,而取决于索引以及需要访问多少表才能生成结果。

如果对查询有疑问,请始终手动运行EXPLAIN以查看问题的实际情况。像这样:

EXPLAIN SELECT comment_approved, COUNT(*) AS total
FROM wp_comments
GROUP BY comment_approved
附加:请注意comment_type 字段没有索引,因此在该字段中添加WHERE子句可能会使查询速度慢得多。这可能是一个合理的关注点,但关注点是表索引,而不是查询。

结束

相关推荐

在WordPress SQL查询中查询多个元键

这是我的问题。。。我希望将此查询的范围缩小到一个特定角色的用户(“meta\\u key=\'wp\\u capabilities\'和meta\\u value=\'employee\'))。。。如何将附加条件添加到此字符串中?$get_users = \"SELECT * FROM $wpdb->users WHERE ID = ANY ( SELECT user_id FROM $wpdb->usermeta WHERE meta_key = \'$meta_ke