WordPress 数据量大列表查询慢 SQL_CALC_FOUND_ROWS 惹的祸
随着文章的不断添加,WordPress 变得越来越慢,特别是列表页面严重的卡顿,查看服务器资源占用也都正常,并不是收到攻击或者是程序问题,由于做了缓存,一直认为是偶现的一时查询慢,并没有在意,但是今天发现卡住的时间特别长,刷新了好几次网页都超时,而且其他的网页也打不开,问题还是比较严重的。
发现问题
打开 Navicat 的服务器监控页面,发现在访问列表页面的时候,一个 SQL 执行老是卡住,导致后面的 SQL 执行只能等待:
单独复制出来查看 SQL:
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE
1=1 AND
wp_posts.post_type = 'doc' AND
(wp_posts.post_status = 'publish')
ORDER BY wp_posts.post_date DESC LIMIT 0, 10
刚开始怀疑是没有走索引,所以很慢,随打开 MySQL 查看索引:
执行 EXPLAIN 查看查询的时候是不是用到了索引:
到这里感觉是没有问题,唯一不同的就是使用了 SQL_CALC_FOUND_ROWS
缓存查询结果:
SQL_CALC_FOUND_ROWS 是在 MySQL 4.0 以后加入的,告诉 MySQL 将 sql 所处理的行数记录下来,然后使用 FOUND_ROWS() 则取到了这个纪录,虽然也是两个语句,但是只执行了一次主查询,所以效率比原来要高很多。
于是我把 SQL_CALC_FOUND_ROWS 去掉:
嚯嚯,这执行结果简直天壤之别,找到问题了,就是这个 SQL_CALC_FOUND_ROWS 搞的鬼。
解决方法
知道问题了,那么就来修改下程序,使用 add_filter 修改这个 SQL 语句:
if(is_tax('docs')){
function posts_select_filter ($fields){
return str_replace('SQL_CALC_FOUND_ROWS', '', $fields);
}
add_filter('posts_request', 'posts_select_filter');
}
不对突然想到一个问题,这样修改以后会不会导致接下来的统计条数出错,后续再来解决吧,先把查询慢的问题解决了。
总结
总的来说,对于少量数据,使用 SQL_CALC_FOUND_ROWS
确实是比较高效,但是如果数据量大就还是老老实实的 count(*)
吧!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论