我有一个MySQL(实际上是MariaDB)查询,当我尝试按DATETIME字段(sighted
)而不是主键进行排序时,它运行得慢得多并且回退到filesort上。我有sighted
的索引,但由于某种原因它似乎没有使用它。如何对此表进行索引,以便可以有效地对DATETIME字段进行排序?
select
user_id , t.name, f.value, y.name
from posts p
left join taxon_sightings t on (t.post_id = p.id)
left join fields f on (f.foreign_id = t.id)
left join fieldtypes y on (y.id = f.fieldtype_id)
group by p.id
order by p.sighted desc
limit 10;
当我按sighted
DATETIME字段排序时:
MariaDB [dbase]> explain [yadda yadda, as above]
+----+-------------+-------+--------+---------------+------------+---------+--------------------------------+------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+---------------+------------+---------+--------------------------------+------+---------------------------------+
| 1 | SIMPLE | p | ALL | NULL | NULL | NULL | NULL | 1759 | Using temporary; Using filesort |
| 1 | SIMPLE | t | ref | post_id | post_id | 4 | dataportal_test.p.id | 12 | |
| 1 | SIMPLE | f | ref | foreign_id | foreign_id | 4 | dataportal_test.t.id | 6 | Using where |
| 1 | SIMPLE | y | eq_ref | PRIMARY | PRIMARY | 4 | dataportal_test.f.fieldtype_id | 1 | Using where |
+----+-------------+-------+--------+---------------+------------+---------+--------------------------------+------+---------------------------------+
比较我按ID排序的时间:
+----+-------------+-------+--------+---------------+------------+---------+--------------------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+---------------+------------+---------+--------------------------------+------+-------------+
| 1 | SIMPLE | p | index | NULL | PRIMARY | 4 | NULL | 1 | |
| 1 | SIMPLE | t | ref | post_id | post_id | 4 | dataportal_test.p.id | 12 | |
| 1 | SIMPLE | f | ref | foreign_id | foreign_id | 4 | dataportal_test.t.id | 6 | Using where |
| 1 | SIMPLE | y | eq_ref | PRIMARY | PRIMARY | 4 | dataportal_test.f.fieldtype_id | 1 | Using where |
+----+-------------+-------+--------+---------------+------------+---------+--------------------------------+------+-------------+
答案 0 :(得分:0)
我认为你不能。我能想到的唯一技巧是试试这个:
select user_id, t.name, f.value, y.name
from posts p left join
taxon_sightings t
on (t.post_id = p.id) left join
fields f
on (f.foreign_id = t.id) left join
fieldtypes y
on (y.id = f.fieldtype_id)
group by p.sighted, p.id
---------^ very important
order by p.sighted desc
limit 10;
然后在posts(sighted, id)
上添加一个索引。带group by
的{{1}}可能会利用索引。如果你很幸运。 。
答案 1 :(得分:0)
假设p.id
中的posts
是唯一的,请让我们摆脱GROUP BY p.id
。我认为它存在的唯一原因是因为JOINs
正在膨胀行数?
除非你需要,否则摆脱LEFT
。
SELECT x.user_id, t.name, f.value, y.name
FROM
( SELECT id, sighted
FROM posts
-- No GROUP BY needed if id is UNIQUE
ORDER BY sighted DESC
LIMIT 10
) AS p
JOIN taxon_sightings t ON (t.post_id = p.id)
JOIN fields f ON (f.foreign_id = t.id)
JOIN fieldtypes y ON (y.id = f.fieldtype_id)
GROUP BY p.id
ORDER BY p.sighted DESC, p.id DESC;
并且(正如戈登建议的那样),INDEX(sighted, id)
。