我有这个查询需要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
编辑解释结果
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)
为什么慢?可以优化吗?如果是,那么如何?
答案 0 :(得分:2)
尝试在
上创建索引ocal_favs ( clipart_id, username )
并确保NOT NULL
上存在ocal_favs.username
约束或添加ocal_favs.username IS NOT NULL
作为条件。
这应该允许从ocal_files
和该索引获取所有信息。
答案 1 :(得分:1)
处理SQL
优化时的一个好方法是选择您需要的字段,而不是所有字段。这几乎总是会对性能产生巨大影响,尤其是当字段为BLOB's
时。
并且,正如其他用户所指出的那样 - 索引也非常重要,但前提是你已经正确创建了索引。
使用LIMIT
条款也是个好主意,如果你不需要立刻显示你的结果(我怀疑这是这种情况,因为我不相信你会显示用户浏览器的30000条记录的结果)...