我已经创建了下面列出的表格测量值。 该表定期写入,并在几天后迅速增长到包含数百万行。 读:我只需要测量的精确时间及其值(unix_epoch和值)。
为了提高性能,我添加了date_from_epoch列,这是从unix_epoch中提取的日期(测量精确时间),格式为:yyyymmdd。它应该具有良好的选择性(在将多天的测量结果写入表格之后)并且我将其用作索引的关键字。我希望只扫描我想要读取测量的天数,而不是扫描表中的所有日期(例如:10天后,如果每天添加1,000,000,我希望只扫描1,000,000行,如果我需要在一天内包含数据,而不是10,000,000)。
我也有:
问题: 测量表在测量表中滴流2天后,我进行了测试。 使用EXPLAIN,我看到我的读取查询不使用索引。为什么查询没有使用索引?
表创建于:
CREATE TABLE measurements(
date_from_epoch INT UNSIGNED,
unix_epoch INT UNSIGNED,
application_name varchar(255),
environment varchar(255),
metric_name varchar(255),
host_name varchar(1024),
value FLOAT(38,3)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
PARTITION BY HASH(unix_epoch)
PARTITIONS 10;
CREATE TRIGGER write_epoch_day
BEFORE INSERT ON measurements
FOR EACH ROW
SET NEW.date_from_epoch = FROM_UNIXTIME(NEW.unix_epoch, '%Y%m%d');
ALTER TABLE measurements ADD INDEX (date_from_epoch);
查询是:
EXPLAIN SELECT * FROM measurements
WHERE date_from_epoch >= 20150615 AND date_from_epoch <= 20150615
AND unix_epoch >= 1434423478 AND unix_epoch <= 1434430678
AND BINARY application_name = 'all'
AND BINARY environment = 'prod'
AND BINARY metric_name = 'Internet availability'
AND (BINARY host_name = 'kitkat' )
ORDER BY unix_epoch ASC;
解释给出:
id select_type table type possible_keys key key_len ref rows Extra
-------------------------------------------------------------------------------------------------------------------------------------------------------
1 SIMPLE measurements ALL date_from_epoch 118011 Using where; Using filesort
感谢阅读和头疼!
答案 0 :(得分:0)
可以选择在MYSQL中使用 FORCE INDEX
请参阅this以便更好地理解。
答案 1 :(得分:0)
谢谢Sashi!
我已将查询修改为
Summer
解释说仍然&#34;使用在哪里;使用文件排序&#34;但扫描的行数现在下降到67,906,相比之下最初扫描的118,011(这很棒)。
虽然date_from_epoch = 20150615的行数是113,182。我现在想知道为什么扫描的行数不是113,182(不是我希望它上升,但我想了解mysql做了什么来进一步优化执行)。
答案 2 :(得分:0)
很多事情需要解决:
PARTITION BY HASH
;它无济于事。EXPLAIN PARTITIONS SELECT ...
。BINARY
。而是将列指定为COLLATION utf8_bin
。性能会好很多。SELECT
运行得更快。FLOAT(38, 3)
有一个额外的(不必要的?)舍入。只需使用FLOAT
。INDEX(application_name, environment, metric_name, host_name, unix_epoch)
会非常有用,至少对于那个查询而言。它会比你要问的INDEX
明显更好。