如何在mysql中调整自连接表?

时间:2013-05-14 21:58:53

标签: mysql performance database-performance

我有这张桌子,我想从中选择和迄今为止。查询花了2分钟在400万条记录上运行。我不确定我能从这个查询中挤出多少。

    SELECT c.fk_id, c.from_date, c.fk_pb, MIN(o.from_date) AS to_date  
    FROM TABLE_X c  
        INNER JOIN TABLE_X o ON c.fk_id =  o.fk_id AND c.fk_pb = o.fk_pb  
WHERE o.from_date > c.from_date  
        GROUP BY c.fk_id, c.from_date, c.fk_pb

from_date,fk_pb和fk_id上已有索引。

架构是这样的。

+-----------------------------+---------------+------+-----+---------+-------+
| Field                       | Type          | Null | Key | Default | Extra |
+-----------------------------+---------------+------+-----+---------+-------+
| FK_ID                       | int(11)       | YES  | MUL | NULL    |       |
| FK_PB                       | int(11)       | YES  | MUL | NULL    |       |
| FROM_DATE                   | date          | YES  | MUL | NULL    |       |
| TO_DATE                     | date          | YES  |     | NULL    |       |
+-----------------------------+---------------+------+-----+---------+-------+

我知道我不应该在MySQL中使用自联接,但数据是这样的,我正在尝试找到从这个表中选择和约会的最佳方法。如果还有什么我可以做的更快,那就更好了。

非常感谢。

已更新

+----+-------------+-------+------+----------------------------------------------------------------------+-------------------------+---------+----------------------------------------+---------+----------------------------------------------+
| id | select_type | table | type | possible_keys                                                        | key                     | key_len | ref                                    | rows    | Extra                                        |
+----+-------------+-------+------+----------------------------------------------------------------------+-------------------------+---------+----------------------------------------+---------+----------------------------------------------+
|  1 | SIMPLE      | c     | ALL  | IDX_FK_PB,IDX_FK_ID,IDX_FRM_DATE                                     | NULL                    | NULL    | NULL                                   | 4527750 | Using where; Using temporary; Using filesort |
|  1 | SIMPLE      | o     | ref  | IDX_FK_PB,IDX_FK_ID,IDX_FRM_DATE                                     | IDX_FK_ID               | 5       | db.c.FK_ID                             |     110 | Using where                                  |
+----+-------------+-------+------+----------------------------------------------------------------------+-------------------------+---------+----------------------------------------+---------+----------------------------------------------+

1 个答案:

答案 0 :(得分:2)

为所有相关列添加索引会加快这一速度:

INDEX(FK_ID, FK_PB,FROM_DATE)

哪个表现更好,因为:

  • MySQL可以为所有行使用索引 c,所以它不需要回到表中(添加一个不在索引中的列会再次减慢它的速度)。
  • MySQL在index merging非常糟糕,因此经常选择不使用它(幸运的是),当它发生时,它通常不是最理想的。
  • 嗯,一个覆盖所有搜索的索引(在这种情况下,加入=搜索)比MySQL选择其中一个索引(限制性最强,SHOW INDEX FROM tablename可以显示基数)更快要使用的单独列,必须扫描其他列中的值。