Mysql 不确定类似表为什么不使用索引
前面的问题必须非常通用,因为我不能像实际情况那样包含数据库/列名 我有两张桌子<代码>表1和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
表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
两个解释之间存在明显差异,但我不确定为什么一个会使用索引、berange
等,而另一个不使用索引和beALL
编辑只是为了添加,我尝试了强制执行
索引(强制执行索引(日期客户)
),该索引显然会在解释
中拾取索引,但查询运行时间完全相同(>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)