SELECT au.*
FROM users au
INNER JOIN friends fa ON au.id = fa.to_user_id
WHERE fa.from_user_id = 369 AND fa.persona_id IN('1241')
GROUP BY au.id
ORDER BY id DESC
LIMIT 0, 9999999999;
这是解释
mysql> EXPLAIN SELECT au.* FROM users au INNER JOIN friends fa ON au.id = fa.to_user_id WHERE fa.from_user_id = 369 AND fa.persona_id IN('1241') GROUP BY au.id ORDER BY id DESC LIMIT 0, 9999999999;
+----+-------------+-------+-------------+------------------------------------------------------------+------------------------------------+---------+--------------------+------+---------------------------------------------------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------------+------------------------------------------------------------+------------------------------------+---------+--------------------+------+---------------------------------------------------------------------------------------------------+
| 1 | SIMPLE | fa | index_merge | from_user_id,to_user_id,persona_id,from_user_id_persona_id | persona_id,from_user_id_persona_id | 4,8 | NULL | 49 | Using intersect(persona_id,from_user_id_persona_id); Using where; Using temporary; Using filesort |
| 1 | SIMPLE | au | eq_ref | PRIMARY | PRIMARY | 4 | kjdb.fa.to_user_id | 1 | |
+----+-------------+-------+-------------+------------------------------------------------------------+------------------------------------+---------+--------------------+------+---------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
我在这张表中只有300,000行,但这是永远的。 (约0.75秒运行它)
mysql> desc friends;
+-------------------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| from_user_id | int(11) | NO | MUL | NULL | |
| to_user_id | int(11) | NO | MUL | NULL | |
| persona_id | int(11) | NO | MUL | NULL | |
| action_by_user_id | int(11) | NO | MUL | NULL | |
| is_disabled | tinyint(1) | NO | | 0 | |
| created_at | datetime | YES | | NULL | |
| updated_at | datetime | YES | | NULL | |
+-------------------+------------+------+-----+---------+----------------+
8 rows in set (0.01 sec)
> desc users;
+---------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| username | varchar(255) | NO | UNI | NULL | |
| first_name | varchar(255) | NO | MUL | NULL | |
| last_name | varchar(255) | YES | MUL | NULL | |
| email | varchar(255) | YES | UNI | NULL | |
这是我的索引:
mysql> show indexes from friends;
+-------------------+------------+-------------------------+--------------+-------------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------------------+------------+-------------------------+--------------+-------------------+-----------+-------------+----------+--------+------+------------+---------+
| friends | 0 | PRIMARY | 1 | id | A | 388926 | NULL | NULL | | BTREE | |
| friends | 0 | from_user_id | 1 | from_user_id | A | 17 | NULL | NULL | | BTREE | |
| friends | 0 | from_user_id | 2 | to_user_id | A | 388926 | NULL | NULL | | BTREE | |
| friends | 0 | from_user_id | 3 | persona_id | A | 388926 | NULL | NULL | | BTREE | |
| friends | 1 | to_user_id | 1 | to_user_id | A | 19446 | NULL | NULL | | BTREE | |
| friends | 1 | persona_id | 1 | persona_id | A | 32410 | NULL | NULL | | BTREE | |
| friends | 1 | action_by_user_id | 1 | action_by_user_id | A | 9972 | NULL | NULL | | BTREE | |
| friends | 1 | from_user_id_persona_id | 1 | from_user_id | A | 9486 | NULL | NULL | | BTREE | |
| friends | 1 | from_user_id_persona_id | 2 | persona_id | A | 35356 | NULL | NULL | | BTREE | |
+-------------------+------------+-------------------------+--------------+-------------------+-----------+-------------+----------+--------+------+------------+---------+
答案 0 :(得分:0)
添加此索引:
ALTER TABLE friends ADD INDEX ix_from_persona_to (from_user_id,persona_id,to_user_id);
看看是否有帮助。
如果没有,您可能需要添加FORCE INDEX
:
SELECT
au.*
FROM
users au
INNER JOIN
friends fa ON au.id = fa.to_user_id
FORCE INDEX
(ix_from_persona_to)
WHERE
fa.from_user_id = 369 AND
fa.persona_id IN ('1241')
GROUP BY
au.id
ORDER BY
id DESC
LIMIT
0, 9999999999;
答案 1 :(得分:0)
on group by的顺序导致临时表+ filesort,这会影响你的表现。
尝试subselects?
SELECT au.*
FROM users au
WHERE au.id IN (
SELECT DISTINCT fa.to_user_id
FRoM friends fa
WHERE fa.from_user_id = 369 AND fa.persona_id IN('1241')
)
ORDER BY id DESC
LIMIT 0, 9999999999;
然后在friends.from_user_id,persona_id
上添加索引