【问题标题】:optimise a mysql query to reduce rows searched优化 mysql 查询以减少搜索的行数
【发布时间】: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,为什么需要 JOINarticles AND users 表?
  • @Eric 所以它可以显示评论所在的文章名称和评论者的用户名。

标签: php mysql query-optimization


【解决方案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 BYLIMIT。最坏的情况是它必须扫描整个表而不找到 5 行。

81,486 是假的。以下是获取优质信息的准确方法:

FLUSH STATUS;
SELECT ...;
SHOW SESSION STATUS LIKE 'Handler%';

“读取”将指示有多少行数据和索引被触及;写入指示正在使用临时表。

【讨论】:

    猜你喜欢
    • 2017-02-15
    • 2013-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-15
    • 1970-01-01
    • 2012-11-09
    相关资源
    最近更新 更多