优化 mysql 查询以减少搜索的行数
Posted
技术标签:
【中文标题】优化 mysql 查询以减少搜索的行数【英文标题】:optimise a mysql query to reduce rows searched 【发布时间】:2019-11-08 16:52:47 【问题描述】:我目前正在抓取我网站上发布的最后 5 个 cmets,我认为这似乎做得很糟糕。
这是 SQL 查询:
SELECT c.comment_id
, c.article_id
, c.time_posted
, a.title
, a.slug
, u.username
FROM articles_comments c
JOIN articles a
ON c.article_id = a.article_id
JOIN users u
ON u.user_id = c.author_id
WHERE a.active = 1
AND c.approved = 1
ORDER
BY c.comment_id DESC
LIMIT 5
我的问题是,必须搜索很多行,这似乎很浪费。我很好奇是否有更好的方法。
这是对它的解释的输出:
如您所见,它给出的行数是 81,486,这看起来有点搞笑。我在这里错过了什么?
【问题讨论】:
也许这会有所帮助:explainextended.com/2009/10/23/… 如果您只需要获取最后 5 个 cmets,为什么需要JOIN
和 articles
AND users
表?
@Eric 所以它可以显示评论所在的文章名称和评论者的用户名。
【参考方案1】:
结果,只是强制articles_cmets 使用PRIMARY 键(comment_id)作为INDEX 修复它。
问题是我的排序选择了所有已批准的 cmets,因此它使用已批准的列进行排序,导致它从数万个中选择数据。
【讨论】:
对未来的另一个考虑。你有 Time_Posted。如果您有大量活动,您甚至可以通过添加… AND Time_Posted > 2 天前来缩短更多时间…除非是一个非常低容量的网站,否则你知道你的活动…那么它就不必再回去了远非如此(前提是时间发布也是一个索引选项)。还要查看 mysql“STRAIGHT_JOIN”子句,它告诉引擎……按照我布置的确切顺序进行查询。不要猜测我的加入条件以获得最佳处理。 不知道 STRAIGHT_JOIN,非常感谢!也会记住这一点。【参考方案2】:c: INDEX(approved, comment_id) -- in this order
a: I assume you have PRIMARY KEY(article_id)
u: I assume you have PRIMARY KEY(user_id)
希望c
索引能够处理一些WHERE
,以及ORDER BY
和LIMIT
。最坏的情况是它必须扫描整个表而不找到 5 行。
81,486 是假的。以下是获取优质信息的准确方法:
FLUSH STATUS;
SELECT ...;
SHOW SESSION STATUS LIKE 'Handler%';
“读取”将指示有多少行数据和索引被触及;写入指示正在使用临时表。
【讨论】:
以上是关于优化 mysql 查询以减少搜索的行数的主要内容,如果未能解决你的问题,请参考以下文章