MySQL日期时间索引不起作用

时间:2010-10-25 09:31:56

标签: mysql database-design

表格结构:

+-------------+----------+------+-----+---------+----------------+
| Field       | Type     | Null | Key | Default | Extra          |
+-------------+----------+------+-----+---------+----------------+
| id          | int(11)  | NO   | PRI | NULL    | auto_increment |
| total       | int(11)  | YES  |     | NULL    |                |
| thedatetime | datetime | YES  | MUL | NULL    |                |
+-------------+----------+------+-----+---------+----------------+

总行数: 137967

mysql> explain select * from out where thedatetime <= NOW();
+----+-------------+-------------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table       | type | possible_keys | key  | key_len | ref  | rows   | Extra       |
+----+-------------+-------------+------+---------------+------+---------+------+--------+-------------+
|  1 | SIMPLE      | out         | ALL  | thedatetime   | NULL | NULL    | NULL | 137967 | Using where |
+----+-------------+-------------+------+---------------+------+---------+------+--------+-------------+

对于更多的表连接,真正的查询要长得多,重点是,我无法让表使用datetime索引。如果我想在特定日期之前选择所有数据,这对我来说将很难。但是,我注意到如果选择较小的数据子集,我可以让MySQL使用索引。

mysql> explain select * from out where thedatetime <= '2008-01-01';
+----+-------------+-------------+-------+---------------+-------------+---------+------+-------+-------------+
| id | select_type | table       | type  | possible_keys | key         | key_len | ref  | rows  | Extra       |
+----+-------------+-------------+-------+---------------+-------------+---------+------+-------+-------------+
|  1 | SIMPLE      | out         | range | thedatetime   | thedatetime | 9       | NULL | 15826 | Using where |
+----+-------------+-------------+-------+---------------+-------------+---------+------+-------+-------------+

mysql> select count(*) from out where thedatetime <= '2008-01-01';
+----------+
| count(*) |
+----------+
|    15990 |
+----------+

那么,无论我投放什么日期,我该怎样做才能确保MySQL会使用索引?

2 个答案:

答案 0 :(得分:11)

这里有两件事 -

  1. 指数不够有选择性 - 如果指数覆盖超过约。 30%的行,MySQL将决定全表扫描更高效。当您收缩该范围时,该指数就会开始。

  2. 联接中每个表的一个索引

  3.   

    真正的查询要长得多   有了更多的表连接,重点是......

    关键是因为它有连接,它可能无法使用该索引。 MySQL可以在连接中为每个表使用一个索引(除非它符合index-merge优化的条件)。如果主键已用于连接,则不会使用日期时间。要使用它,您需要以正确的顺序在连接键+ thedatetime索引上创建多列索引。

    检查实际查询的EXPLAIN以查看MySQL用于连接的密钥。修改该索引以包含thedatetime列,或者从两者创建一个新的多列索引(取决于您使用连接键的内容)。

答案 1 :(得分:7)

一切都按预期运作。 :)

索引可以加快检索速度。他们使用索引查找来完成它。

在您第一次查询时,未使用索引,因为您正在检索所有行,在这种情况下使用索引较慢(lookup indexget rowlookup index,{{1} } ... x行数慢于get row ==表扫描)

在第二个查询中,您只检索一部分数据,在这种情况下,表扫描要慢得多。

优化器的工作是使用RDBMS保留在索引上的统计信息来确定最佳计划。在第一种情况下,考虑了索引,但是计划者(正确地)将其扔掉了。

修改
您可能希望阅读this之类的内容,以获取有关mysql查询规划器的一些概念和关键字。