2015-06-25 32 views
0

当我尝试按DATETIME字段排序(sighted)时,我有一个MySQL(实际上是MariaDB)查询,运行速度慢得多,而不是主键。我有一个sighted索引,但由于某种原因,它似乎没有使用它。我如何索引这个表,以便它可以有效地按照DATETIME字段排序?当按datetime排序时,加入重型MySQL查询变慢,而不是按ID排序缓慢

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 | 
+----+-------------+-------+--------+---------------+------------+---------+--------------------------------+------+-------------+ 
+1

这听起来像索引问题。您是否向日期时间列添加了索引,以便可以优化查询?介意分享表格定义? – MiltoxBeyond

+0

是的,我做了,但它没有使用它(这是令人困惑的!)。 – schnauss

+0

请为表格提供'SHOW CREATE TABLE'。 –

回答

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 byorder by可能会利用索引。如果你幸运的话。 。 。

0

假设p.idposts中是唯一的,我们来摆脱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)