MySQL日期时间索引不工作

MySQL日期时间索引不工作,mysql,database-design,Mysql,Database Design,表结构: +-------------+----------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------+----------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL

表结构:

+-------------+----------+------+-----+---------+----------------+
| 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 |
+----+-------------+-------------+------+---------------+------+---------+------+--------+-------------+

那么,我该怎么做才能确保MySQL将使用该索引,而不管我放在什么日期?

这里有两件事要做-

  • 索引的选择性不够-如果索引覆盖了大约30%的行,MySQL将决定进行全表扫描更有效。当你缩小范围时,指数开始生效

  • 联接中的每个表一个索引

  • 真正的查询要长得多 有了更多的表联接,关键是

    这一点正是因为它有连接,所以它可能无法使用该索引。MySQL可以在联接中为每个表使用一个索引(除非它符合优化条件)。如果主键已用于联接,则不会使用DateTime。为了使用它,您需要按照正确的顺序在join键+DateTime索引上创建多列索引


    检查实际查询的解释,查看MySQL使用哪个键进行连接。修改该索引以同时包含DateTime列,或从这两个列创建新的多列索引(取决于您使用join键的目的)。

    一切都按预期工作。:)

    索引是用来加速检索的。他们使用索引查找来实现这一点

    在第一次查询中,索引不被使用,因为您正在检索所有行,在这种情况下,使用索引的速度较慢(
    查找索引
    获取行
    查找索引
    获取行
    …x行数比
    获取所有行
    ==表扫描)

    在第二个查询中,您只检索一部分数据,在本例中,表扫描要慢得多

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

    编辑

    您可能需要阅读一些类似于获取有关mysql query planner的概念和关键字的内容。

    正如
    解释
    告诉您索引已被“使用”,或者更准确地说,在这两种情况下都会考虑索引。我下面的回答详细解释了这一点。另一方面,如果你的表现不佳,那么你将问题简化得太多了。我想这就是原因(我尝试将这个答案应用到其他表格中)。我需要阅读更多关于MySQL索引的内容,所以感谢您的链接。当他在第二次查询中运行explain子句时,在额外的一列中,它会说“使用where”,这不意味着这是完整的表扫描吗?感谢您的第一个答案和解释,但由于他/她先回答了问题,所以我必须标记为未读。他很好地解释了为什么非选择性索引的索引查找速度较慢
    
    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 |
    +----------+