表格结构:
+-------------+----------+------+-----+---------+----------------+
| 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会使用索引?
答案 0 :(得分:11)
这里有两件事 -
指数不够有选择性 - 如果指数覆盖超过约。 30%的行,MySQL将决定全表扫描更高效。当您收缩该范围时,该指数就会开始。
联接中每个表的一个索引
真正的查询要长得多 有了更多的表连接,重点是......
关键是因为它有连接,它可能无法使用该索引。 MySQL可以在连接中为每个表使用一个索引(除非它符合index-merge优化的条件)。如果主键已用于连接,则不会使用日期时间。要使用它,您需要以正确的顺序在连接键+ thedatetime索引上创建多列索引。
检查实际查询的EXPLAIN以查看MySQL用于连接的密钥。修改该索引以包含thedatetime列,或者从两者创建一个新的多列索引(取决于您使用连接键的内容)。
答案 1 :(得分:7)
一切都按预期运作。 :)
索引可以加快检索速度。他们使用索引查找来完成它。
在您第一次查询时,未使用索引,因为您正在检索所有行,在这种情况下使用索引较慢(lookup index
,get row
,lookup index
,{{1} } ... x行数慢于get row
==表扫描)
在第二个查询中,您只检索一部分数据,在这种情况下,表扫描要慢得多。
优化器的工作是使用RDBMS保留在索引上的统计信息来确定最佳计划。在第一种情况下,考虑了索引,但是计划者(正确地)将其扔掉了。
修改强>
您可能希望阅读this之类的内容,以获取有关mysql查询规划器的一些概念和关键字。