上述问题必须非常通用,因为我不能包含数据库/列名称,因为它们实际上是。不确定为什么一个类似的表不使用索引
我有两个表; table1
和table2
。这两个表都有相同的索引; DATE_CUSTOMER
它由DATE
字段和Customer_Name
字段组成。
table1
有24,127,915
行和table2
有30,821,313
行。
查询:
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)
从table1
响应:
* id: 1
* select_type: SIMPLE
* table: table1
* type: range
* possible_keys: DATE_CUSTOMER
* key: DATE_CUSTOMER
* key_len: 8
* ref: (NULL)
* rows: 856,782
* Extra: Using index condition; Using temporary; Using filesort
从table2
响应:
* 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
有两个EXPLAINS
但我明显区别不确定为什么会使用索引,是range
等,以及其他不使用索引,并ALL
编辑我想补充我曾尝试Forcing
指数(FORCE INDEX (DATE_CUSTOMER)
),这显然挑选指数最高的EXPLAIN
但查询运行时是完全相同(> 9分钟)。
如果MySQL不会减少它必须扫描的行数,MySQL将不会使用该索引。您的餐桌2总计约有3100万美元中的约2800万美元。这意味着很多记录满足'WHERE'子句。索引在这里没用,它不能帮助MySQL更少地扫描数据。使用索引可能会导致性能损失,因为它必须读取索引,而索引根本没有帮助,然后读取数据。你强制索引,你注意到执行时间保持不变。此外,它确实需要大量的时间来查找/读取/缓冲/发送如此多的行。 – Mjh
@RickJames数学中的'〜'意味着*近似*相等,或者如果您将*估计*。我用那个符号。我也从来没有说'EXPLAIN'估计要返回**的行数,所以我完全不知道为什么你甚至会突出显示我。 – Mjh
我用“从〜31M返回〜28M”:“type:ALL”和“key:(NULL)”得出结论说,_entire_表将被_scanned_,而不仅仅是〜28 /〜31。表2中的数字'EXPLAIN'甚至没有估计有多少行将返回_returned_。 –