MySQL如何确定它是否使用GROUP BY的索引?

时间:2011-12-08 02:54:21

标签: mysql sql

我有一张简单的表

stock_ledger_id   INT(10) (Primary)
piece_to_bin_id   INT(10)
quantity          INT(11)
create_datetime   TIMESTAMP
... and a few VARCHARs

有一些简单的索引

Key_name          Cardinality
PRIMARY               1510443
piece_to_bin_id        100696

这个相当简单的查询大约需要8秒钟:

SELECT piece_to_bin_id,
       SUM(quantity),
       MAX(create_datetime)
FROM stock_ledger
GROUP BY piece_to_bin_id

这是EXPLAIN:

id select_type table        type possible_keys key  key_len ref  rows    Extra                           
1  SIMPLE      stock_ledger ALL  NULL          NULL NULL    NULL 1512976 Using temporary; Using filesort 

通过强制索引,我发现我可以将其降低到约.5秒

SELECT piece_to_bin_id,
       SUM(quantity),
       MAX(create_datetime)
FROM stock_ledger
FORCE INDEX (piece_to_bin_id)
GROUP BY piece_to_bin_id

然后EXPLAIN看起来像这样:

id select_type table        type  possible_keys key             key_len ref  rows    Extra
1  SIMPLE      stock_ledger index NULL          piece_to_bin_id 4       NULL 1512976

我使用的是MySQL 5.1.41,表格是MyISAM,之前我确实运行过ANALYZE TABLE。

所以我坚持“MySQL再次出错,只是强制索引”或者是否存在MySQL使用全表扫描的实际原因?也许我能解决一个问题?

1 个答案:

答案 0 :(得分:1)

无论如何,查询需要一个完整的表扫描,可能是mysql试图避免从键值到行的额外转换。查询可能更多地受益于复合(piece_to_ bin_id,create_datetime)索引或甚至(piece_to_ bin_id,create_datetime,quantity)。后者将成为覆盖指数。

<强> UPD

在您的情况下,似乎更快16倍的结果来自数据分布(可能是许多相邻的行具有相同的piece_to_bin_idcreate_datetime排序)。 MyISAM似乎使用索引来减少结果行的数量,因为使用它们意味着随机磁盘I / O操作。

我从来没有引起任何关注,但我目前对10K行表的测试表明,MyISAM甚至没有使用索引来对查询进行排序,如:

SELECT indexed_field, another_field
FROM a_table
ORDER BY indexed_field;

即使indexed_field是主键。