避免使用ORDER BY“使用临时”和“使用filesort”

时间:2013-01-14 11:37:52

标签: mysql sql-order-by query-optimization

抱歉,但在浏览了几乎所有关于它的帖子和问题之后,我仍然无法在一个简单的查询中摆脱“使用临时”和“使用filesort”。我知道这是钥匙的问题,但我找不到合适的组合......

我也不知道优化器定义的连接顺序是否正常,我使用STRAIGHT_JOIN测试了其他订单,但没有更好......使用ORDER BY查询速度非常慢,但没有它和当然没有“使用临时”和“使用filesort”! (在点表中有大约100.000行)

查询:

SELECT points.id,
points.id_owner,
points.point_title,
points.point_desc,
users.user_id,
users.username
FROM points,
JOIN users ON points.id_owner = users.user_id
JOIN follows ON follows.id_followed = points.id_owner
WHERE points.deleted = 0
AND follows.id_follower = 22
ORDER BY points.id DESC
LIMIT 10

解释:

+----+-------------+---------+--------+---------------+------------+---------+---------------------+------+----------------------------------------------+
| id | select_type | table   | type   | possible_keys | key        | key_len | ref                 | rows | Extra                                        |
+----+-------------+---------+--------+---------------+------------+---------+---------------------+------+----------------------------------------------+
|  1 | SIMPLE      | follows | ref    | FOLLOW_DUO    | FOLLOW_DUO | 4       | const               |    2 | Using index; Using temporary; Using filesort |
|  1 | SIMPLE      | users   | eq_ref | PRIMARY       | PRIMARY    | 4       | follows.id_followed |    1 |                                              |
|  1 | SIMPLE      | points  | ref    | GETPOINT1     | GETPOINT1  | 5       | users.user_id,const |  460 | Using where                                  |
+----+-------------+---------+--------+---------------+------------+---------+---------------------+------+----------------------------------------------+

以下是三个表中的SHOW INDEX:

SHOW INDEX FROM points
+--------+------------+--------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+
| Table  | Non_unique | Key_name     | Seq_in_index | Column_name     | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+--------+------------+--------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+
| points |          0 | PRIMARY      |            1 | id              | A         |       91987 |     NULL | NULL   |      | BTREE      |         |
| points |          0 | GETPOINT1    |            1 | id_owner        | A         |        NULL |     NULL | NULL   |      | BTREE      |         |
| points |          0 | GETPOINT1    |            2 | deleted         | A         |        NULL |     NULL | NULL   |      | BTREE      |         |
| points |          0 | GETPOINT1    |            3 | id              | A         |       91987 |     NULL | NULL   |      | BTREE      |         |
+--------+------------+--------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+

SHOW INDEX FROM users
+-------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name   | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| users |          0 | PRIMARY    |            1 | user_id     | A         |           4 |     NULL | NULL   |      | BTREE      |         |
+-------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+

SHOW INDEX FROM follows
+---------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table   | Non_unique | Key_name    | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+---------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| follows |          0 | PRIMARY     |            1 | id          | A         |           5 |     NULL | NULL   |      | BTREE      |         |
| follows |          0 | FOLLOW_DUO  |            1 | id_follower | A         |        NULL |     NULL | NULL   |      | BTREE      |         |
| follows |          0 | FOLLOW_DUO  |            2 | id_followed | A         |           5 |     NULL | NULL   |      | BTREE      |         |
| follows |          1 | id_follower |            1 | id_follower | A         |        NULL |     NULL | NULL   |      | BTREE      |         |
| follows |          1 | id_followed |            1 | id_followed | A         |        NULL |     NULL | NULL   |      | BTREE      |         |
+---------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+

从现在起我不知道要测试什么来试图避免“使用临时”和“使用filesort”......所以,如果你对我有所了解......请提前感谢你的帮助! / p>

1 个答案:

答案 0 :(得分:0)

看起来正在从点表中检查这么多行。我曾尝试过以下技巧,以避免在我的项目中使用临时表。请按照以下步骤进行解释,看看是否有任何改进:

  1. 删除除主键索引表单点表之外的所有名为'GETPOINT1'的索引。
  2. 在列(deleted, id_owner)上添加覆盖索引。请按照提及的方式保留列的顺序。
  3. 如果您仍然没有看到任何改进,请删除上面的索引,然后按(id, deleted, id_owner)(deleted, id_owner, id)列重新添加索引,然后重试
  4. 此外,您可以从where子句中删除follows.id_follower = 22,并将其置于JOIN follows ON follows.id_followed = points.id_owner AND follows.id_follower = 22
  5. 等连接条件中
  6. 请同时在(id_follower, id_owner)表中按follows添加索引。
  7. 我不保证,但上面应该可以给你改进。