我面临索引编制问题。我不明白为什么索引有时对同一查询不起作用。
在以下情况下,索引工作正常
EXPLAIN SELECT `table_name`.* FROM `table_name`
WHERE (created_date between '2018-08-11' and '2018-08-11');
| id | select_type |桌子|隔板|类型
| 1 |简单table_name | NULL |参考| index_table_name_created_date | table_name_created_date | 4 | const | 11 | 1.00 |使用索引条件;在哪里使用 + ---- + ------------- + ------------------- + ---------- -+ ------ + -------------------------------------- +- ------------------------------------- + --------- +- ----- + ------ + ---------- + -------------------------- ---------- + 设置1行,警告1次(0.01秒)
如果我增加日期范围索引,则无法正常工作
EXPLAIN SELECT `table_name`.* FROM `table_name`
WHERE (created_date between '2018-08-11' and '2018-09-11');
+----+-------------+-------------------+------------+------+--------------------------------------+------+---------+------+------+----------+-------------+
| id | select_type |桌子|隔板|类型 可能的钥匙|关键key_len |参考|行|过滤额外| + ---- + ------------- + ------------------- + ---------- -+ ------ + ------------------ | 1 |简单table_name | NULL |全部| index_table_name_created_date | NULL | NULL | NULL | 1233 | 0.30 |在哪里使用 + ---- + ------------- + ------------------- + ---------- -+ ------ + -------------------------------------- +- ----- + --------- + ------ + ------ + ---------- + --------- ---- + 设置1行,1警告(0.00秒)
有人可以帮助我处理此案吗?因此,我的查询需要更长的时间来执行。
答案 0 :(得分:0)
这里的主要概念是您在表上执行SELECT *
,它告诉MySQL您想为返回的每个记录从表中返回 all 列。尽管您可能在created_date
列上有一个索引,但是MySQL可能选择不与SELECT *
一起使用它。这样做的原因是,一旦MySQL遍历B树到达每个叶节点,那里仅存在created_date
的数据。对于其他列,MySQL将不得不对聚集索引进行额外的搜索,以获取其他列的数据。因此,使用索引可能对查询没有帮助。
关于为什么在第一种情况下使用索引,优化器可能已经意识到只有一条匹配记录,然后决定仍然使用索引。确实,如果从查询返回许多记录,您的示例会更好。
下面是一个查询示例,它可以使用索引:
SELECT created_date
FROM yourTable
WHERE created_date BETWEEN '2018-08-11' AND '2018-08-11';
在这种情况下,索引包含我们尝试选择的所有列。如果您想选择另一列,例如col1
,则可以将col1
添加到索引中(这样索引现在位于(created_date, col1)
上),然后以下查询也可以使用索引:
SELECT created_date, col1
FROM yourTable
WHERE created_date BETWEEN '2018-08-11' AND '2018-08-11';