我有数百万条记录的大桌子。下面的查询仅执行0.2秒,这很好。
SELECT ch1.*
FROM citizens_history ch1
WHERE ch1.update_id_to = (
SELECT MAX( ch2.update_id_to )
FROM citizens_history ch2
WHERE ch2.id = ch1.id
)
ORDER BY ch1.experience DESC
LIMIT 100
但是,当我尝试添加INNER JOIN时,就像这样
SELECT ch1.*, upd.*
FROM citizens_history ch1
INNER JOIN updates upd ON upd.id = ch1.update_id_to
WHERE ch1.update_id_to = (
SELECT MAX( ch2.update_id_to )
FROM citizens_history ch2
WHERE ch2.id = ch1.id
)
ORDER BY ch1.experience DESC
LIMIT 100
执行需要永远。在第一种情况下,我认为MySQL正在这样做:
在第二种情况下,我认为会发生这种情况:
您有什么建议我如何优化它?
修改:探索快速和慢速查询:
+----+--------------------+-------+-------+---------------+------------+---------+--------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+-------+-------+---------------+------------+---------+--------------+------+-------------+
| 1 | PRIMARY | ch1 | index | NULL | experience | 3 | NULL | 100 | Using where |
| 2 | DEPENDENT SUBQUERY | ch2 | ref | id | id | 3 | db.ch1.id | 1 | Using index |
+----+--------------------+-------+-------+---------------+------------+---------+--------------+------+-------------+
+----+--------------------+-------+-------+-------------------------------------+----------+---------+--------------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+-------+-------+-------------------------------------+----------+---------+--------------+------+----------------------------------------------+
| 1 | PRIMARY | upd | index | PRIMARY | datetime | 5 | NULL | 389 | Using index; Using temporary; Using filesort |
| 1 | PRIMARY | ch1 | ref | PRIMARY,update_id_to,update_id_to_2 | PRIMARY | 4 | db.upd.id | 112 | Using where |
| 2 | DEPENDENT SUBQUERY | ch2 | ref | id | id | 3 | db.ch1.id | 1 | Using index |
+----+--------------------+-------+-------+-------------------------------------+----------+---------+--------------+------+----------------------------------------------+
答案 0 :(得分:2)
重写第一个查询,如下所示,然后根据需要进行修改......
SELECT ch1.*
FROM citizens_history ch1
JOIN
( SELECT id
, MAX(update_id_to) max_update_id_to
FROM citizens_history
GROUP
BY id
) ch2
ON ch2.id = ch1.id
AND ch2.max_update_id_to = ch1.update_id_to
ORDER
BY ch1.experience DESC
LIMIT 100
如果您仍在努力(表现性能),请为上述内容提供一个EXPLAIN以及所有相关表格的正确DDLS。
答案 1 :(得分:0)
将第一个阶段作为JOIN连接到子查询,然后加入更新表: -
SELECT ch1.*, upd.*
FROM citizens_history ch1
INNER JOIN
(
SELECT id, MAX( update_id_to ) AS max_update_id_to
FROM citizens_history
GROUP BY id
) ch2 ON ch1.id = ch2.id AND ch1.update_id_to = ch2.max_update_id_to
INNER JOIN updates upd ON upd.id = ch1.update_id_to
ORDER BY ch1.experience DESC
LIMIT 100
答案 2 :(得分:0)
您可以尝试:
SELECT ch1.*
FROM citizens_history ch1
LEFT JOIN citizens_history ch2
ON ch2.id = ch1.id
AND ch1.max_update_id_to > ch2.update_id_to
WHERE ch1.max_update_id_to is null
ORDER BY ch1.experience DESC
LIMIT 100