2017-03-09 18 views
0

上述问题必须非常通用,因为我不能包含数据库/列名称,因为它们实际上是。不确定为什么一个类似的表不使用索引

我有两个表; table1table2。这两个表都有相同的索引; DATE_CUSTOMER它由DATE字段和Customer_Name字段组成。

table124,127,915行和table230,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分钟)。

+1

如果MySQL不会减少它必须扫描的行数,MySQL将不会使用该索引。您的餐桌2总计约有3100万美元中的约2800万美元。这意味着很多记录满足'WHERE'子句。索引在这里没用,它不能帮助MySQL更少地扫描数据。使用索引可能会导致性能损失,因为它必须读取索引,而索引根本没有帮助,然后读取数据。你强制索引,你注意到执行时间保持不变。此外,它确实需要大量的时间来查找/读取/缓冲/发送如此多的行。 – Mjh

+0

@RickJames数学中的'〜'意味着*近似*相等,或者如果您将*估计*。我用那个符号。我也从来没有说'EXPLAIN'估计要返回**的行数,所以我完全不知道为什么你甚至会突出显示我。 – Mjh

+0

我用“从〜31M返回〜28M”:“type:ALL”和“key:(NULL)”得出结论说,_entire_表将被_scanned_,而不仅仅是〜28 /〜31。表2中的数字'EXPLAIN'甚至没有估计有多少行将返回_returned_。 –

回答

-1

在该范围内有多少行

请提供SHOW CREATE TABLE - 我们需要查看各种东西,包括什么INDEX date_customer (...)说什么和什么数据类型DATE是。这也可能有助于解释Using index condition,根据您向我们展示的内容,这没有意义。

这是这些查询的最佳指标:

INDEX(date) 

回到问题。 (对于我的问题有待回答,我会做出一些猜测。)

如果索引可以过滤行数小于(约)20%的表,那么将使用该索引。这将涉及BTree指数和Data BTree之间的反弹。对于表1,显然这个数字是3%。

否则,优化器会决定忽略索引并简单扫描数据会更快。我们无法看到table2的%。

另一种猜测是“统计数据”被搞砸了。这是不太可能的,特别是在新版本中。但是,你可以做ANALYZE TABLE table2;看看是否“修复”了“问题”。

相关问题