这个 MySQL 连接查询可以优化吗?

Posted

技术标签:

【中文标题】这个 MySQL 连接查询可以优化吗?【英文标题】:Can this MySQL join query be optimized? 【发布时间】:2012-07-02 11:34:05 【问题描述】:

我有这个查询需要 27 秒才能执行:

SELECT ocal_files.*, count(DISTINCT ocal_favs.username) as favs 
FROM ocal_files
   INNER JOIN ocal_favs on ocal_favs.clipart_id = ocal_files.id 
GROUP BY ocal_files.id 
ORDER BY favs DESC​

(应该是 user_id 而不是用户名,因为我有用户表)

ocal_files 有 37457 行,ocal_favs 有 18263

EDIT解释结果

mysql> EXPLAIN SELECT ocal_files.*, count(DISTINCT ocal_favs.username) as favs FROM ocal_files INNER JOIN ocal_favs on ocal_favs.clipart_i
d = ocal_files.id GROUP BY ocal_files.id ORDER BY favs DESC;                                                                             
+----+-------------+------------+--------+----------------+---------+---------+---------------------------------+-------+---------------------------------+
| id | select_type | table      | type   | possible_keys  | key     | key_len | ref                             | rows  | Extra                           |
+----+-------------+------------+--------+----------------+---------+---------+---------------------------------+-------+---------------------------------+
|  1 | SIMPLE      | ocal_favs  | ALL    | rlb_clipart_id | NULL    | NULL    | NULL                             | 18622 | Using temporary; Using filesort|
|  1 | SIMPLE      | ocal_files | eq_ref | PRIMARY        | PRIMARY | 4       | openclipart.ocal_favs.clipart_id |     1 | Using where                    |
+----+-------------+------------+--------+----------------+---------+---------+---------------------------------+-------+---------------------------------+
2 rows in set (0.00 sec)

为什么慢?可以优化吗?如果是,那么如何?

【问题讨论】:

您的表格是否已编入索引? 执行计划是什么?所涉及的表上的索引是什么? 你有ANALYZEd 你的桌子了吗?能否请 MySQL EXPLAIN 查询? @SimonRichter 我添加了 EXPLAIN 的结果,不知道 ANALYZE 它的速度高达 3.5 秒 【参考方案1】:

尝试创建索引

ocal_favs ( clipart_id, username )

并确保ocal_favs.username 上存在NOT NULL 约束或添加ocal_favs.username IS NOT NULL 作为条件。

这应该允许从ocal_files 和该索引获取所有信息。

【讨论】:

我以前从未使用过索引,是否需要调用此查询:CREATE INDEX favs_index ON ocal_favs (clipart_id, username)? 因为我相信人们,而且我听说索引可以提高性能。 索引当然可以提高性能,我认为这个可以帮助你,但不要相信任何你可以测试的东西:)【参考方案2】:

处理SQL 优化时的一个好方法是只选择您需要的字段,而不是在您的情况下选择所有字段。这几乎总是会对性能产生巨大影响,尤其是当字段为BLOB's 时。 而且,正如其他用户所指出的 - 索引也非常重要,但前提是您已正确创建它。 使用LIMIT 子句也是个好主意,如果您不需要立即显示结果(我怀疑这里是这种情况,因为我不相信您会显示结果30000+ 条记录到用户浏览器)...

【讨论】:

以上是关于这个 MySQL 连接查询可以优化吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何优化 MySQL 中的多个左连接?

优化返回大量记录的查询,避免数百个连接。这是一个聪明的解决方案吗?

如何优化这个 MySql 查询 - 连接 3 个表?

mysql中,如何向测试人员介绍连接查询和子查询的优劣势?

这个查询不好吗? MySql 一对多与左连接和嵌套查询

mysql SELECT LEFT JOIN ON 查询总是超时,大侠能帮忙优化一下吗?