前面的问题必须非常通用,因为我不能像实际那样包含数据库/列名称。
我有两张桌子; 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分钟)。
答案 0 :(得分:-1)
该范围内的多少行?
请提供SHOW CREATE TABLE
- 我们需要查看各种内容,包括INDEX date_customer (...)
所说的内容以及DATE
的数据类型。这也可能有助于解释Using index condition
,根据您向我们展示的内容,这是没有意义的。
这是这些查询的最佳索引:
INDEX(date)
回到问题。 (等待我的问题的答案,我会做出一些猜测。)
如果索引可以将行数过滤到小于(约)20%的表,则将使用索引。这将涉及索引BTree和数据BTree之间的弹跳。对于table1,显然这个数字是3%。
否则,优化器会确定忽略索引并简单地扫描数据会更快。我们无法看到table2的%是什么。
另一个猜测是“统计数据”搞砸了。这不太可能,尤其是在较新版本中。但是,您可以ANALYZE TABLE table2;
查看是否“修复了”“问题”。