Mysql 不确定类似表为什么不使用索引

Mysql 不确定类似表为什么不使用索引,mysql,sql,mariadb,Mysql,Sql,Mariadb,前面的问题必须非常通用,因为我不能像实际情况那样包含数据库/列名 我有两张桌子表1和表2。这两个表都有相同的索引日期\客户由日期字段和客户名称字段组成 table1有24127915行,table2有30821313行 查询: EXPLAIN SELECT Customer, Server, WEEKDAY(DATE), HOUR(DATE), AVG(CPU) FROM table1/table2 WHERE

前面的问题必须非常通用,因为我不能像实际情况那样包含数据库/列名

我有两张桌子<代码>表1和
表2
。这两个表都有相同的索引<代码>日期\客户由
日期
字段和
客户名称
字段组成

table1
24127915
行,
table2
30821313

查询:

   EXPLAIN
   SELECT
     Customer,
     Server,
     WEEKDAY(DATE),
     HOUR(DATE),
     AVG(CPU)
   FROM
     table1/table2
   WHERE
     DATE >= CURDATE() - INTERVAL 7 DAY AND
     DATE < CURDATE() + INTERVAL 1 DAY
   GROUP BY
     Customer,
     Server,
     WEEKDAY(DATE),
     HOUR(DATE)
来自
表2的响应:

* id: 1
* select_type: SIMPLE
* table: table2
* type: ALL
* possible_keys: DATE_CUSTOMER
* key: (NULL)
* key_len: (NULL)
* ref: (NULL)
* rows: 27,958,213
* Extra: Using index condition; Using temporary; Using filesort
两个
解释之间存在明显差异,但我不确定为什么一个会使用索引、be
range
等,而另一个不使用索引和be
ALL

编辑只是为了添加,我尝试了
强制执行
索引(
强制执行索引(日期客户)
),该索引显然会在
解释
中拾取索引,但查询运行时间完全相同(>9分钟)。

该范围内有多少行

请提供
SHOW CREATE TABLE
——我们需要查看各种内容,包括
客户(…)
所说的索引日期以及
日期的数据类型。这也可能有助于解释使用索引条件的
,根据您向我们展示的内容,这是没有意义的

这是这些查询的最佳索引:

INDEX(date)
回到问题上来。(待回答我的问题时,我会做一些猜测。)

如果索引可以将行数过滤到表的20%以下,则将使用索引。这将涉及在索引BTree和数据BTree之间跳转。表1中的数字显然是3%

否则,优化器会认为忽略索引并简单地扫描数据会更快。我们看不到表2的百分比是多少


另一种猜测是“统计数字”混乱不堪。这是不可能的,尤其是在较新的版本中。但是,您可以
分析表2
查看是否“修复”了“问题”。

MySQL不会使用索引,如果它不能帮助减少必须扫描的行数。您的表2返回了约3100万个总数中的约2800万个。这意味着许多记录满足
WHERE
子句。索引在这里是无用的,它不能帮助MySQL更少地扫描数据。使用索引可能会导致性能损失,因为它必须先读取索引(这对它毫无帮助),然后再读取数据。您强制执行索引,并注意到执行时间保持不变。另外,查找/读取/缓冲/发送这么多行肯定要花费大量的时间。@RickJames数学中的
~
表示近似相等,或者如果你愿意的话-估计。我用了那个符号。我也从来没有说过
EXPLAIN
估计了要返回的行数,所以我完全不知道你为什么要突出显示我。我用“31M中的28M个返回值”来反驳:“type:ALL”和“key:(NULL)”表示将扫描整个表,而不仅仅是~28/~31。表2中没有数字解释,甚至没有数字估计将返回多少行。
INDEX(date)