我正在寻找一些有关MySQL表格上的索引如何工作的见解,因为我遇到了一些我不明白的问题。一张桌子上没有被使用的索引
让我们开始与我一起工作的表:
mysql> SHOW CREATE TABLE channeldata\G
*************************** 1. row ***************************
Table: channeldata
Create Table: CREATE TABLE `channeldata` (
`channel_id` smallint(3) unsigned NOT NULL,
`station_id` smallint(5) unsigned NOT NULL,
`time` datetime NOT NULL,
`reading` double NOT NULL DEFAULT '0',
`average` double NOT NULL DEFAULT '0',
`location_lat` double NOT NULL DEFAULT '0',
`location_lon` double NOT NULL DEFAULT '0',
`location_alt` double(8,3) DEFAULT '0.000',
`quality` smallint(3) unsigned DEFAULT '0',
PRIMARY KEY (`channel_id`,`station_id`,`time`),
KEY `composite3` (`station_id`,`channel_id`,`quality`) USING BTREE,
KEY `composite` (`channel_id`,`station_id`,`time`,`quality`) USING BTREE
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
/*!50100 PARTITION BY RANGE (YEAR(time))
(PARTITION p0 VALUES LESS THAN (2001) ENGINE = MyISAM,
PARTITION p1 VALUES LESS THAN (2002) ENGINE = MyISAM,
PARTITION p2 VALUES LESS THAN (2003) ENGINE = MyISAM,
PARTITION p3 VALUES LESS THAN (2004) ENGINE = MyISAM,
PARTITION p4 VALUES LESS THAN (2005) ENGINE = MyISAM,
PARTITION p5 VALUES LESS THAN (2006) ENGINE = MyISAM,
PARTITION p6 VALUES LESS THAN (2007) ENGINE = MyISAM,
PARTITION p7 VALUES LESS THAN (2008) ENGINE = MyISAM,
PARTITION p8 VALUES LESS THAN (2009) ENGINE = MyISAM,
PARTITION p9 VALUES LESS THAN (2010) ENGINE = MyISAM,
PARTITION p10 VALUES LESS THAN (2011) ENGINE = MyISAM,
PARTITION p11 VALUES LESS THAN (2012) ENGINE = MyISAM,
PARTITION p12 VALUES LESS THAN (2013) ENGINE = MyISAM,
PARTITION p13 VALUES LESS THAN (2014) ENGINE = MyISAM,
PARTITION p14 VALUES LESS THAN (2015) ENGINE = MyISAM,
PARTITION p15 VALUES LESS THAN (2016) ENGINE = MyISAM,
PARTITION p16 VALUES LESS THAN (2017) ENGINE = MyISAM,
PARTITION p17 VALUES LESS THAN (2018) ENGINE = MyISAM) */
1 row in set (0.00 sec)
我运行查询在2017年的“解读”八月/九月/十月选择数据通过一天均匀地分布,并总是在10分钟的边界上(即10:10:00,10:20:00,10:30:00等)。从2017年5月起,每天“读数”的数量相当一致,为15.000。 P17分区总共有300多万个读数。
查询我想一些帮助,看起来像这样:
SELECT
ROUND(`a`.`average`,2) `average`,
UNIX_TIMESTAMP(`a`.`time`) * 1000 time,
`a`.`station_id`
FROM
`argus`.`channeldata` PARTITION (p17) `a`
WHERE
((`a`.`station_id` = '3002' AND a.channel_id = '1') OR (`a`.`station_id` = '3004' AND a.channel_id = '1') OR [...] OR (`a`.`station_id` = '5052' AND a.channel_id = '1')) AND `a`.`time` BETWEEN "2017-08-17 00:00:00" AND "2017-10-13 23:59:59" AND `a`.`quality` IN('1') ORDER BY `a`.`time` ASC;
下面是查询格式清楚地显示WHERE
条件。
SELECT
ROUND(`a`.`average`,2) `average`,
UNIX_TIMESTAMP(`a`.`time`) * 1000 time,
`a`.`station_id`
FROM
`argus`.`channeldata` PARTITION (p17) `a`
WHERE
( (`a`.`station_id` = '3002' AND a.channel_id = '1')
OR (`a`.`station_id` = '3004' AND a.channel_id = '1')
OR [...]
OR (`a`.`station_id` = '5052' AND a.channel_id = '1'))
AND `a`.`time` BETWEEN "2017-08-17 00:00:00" AND "2017-10-13 23:59:59"
AND `a`.`quality` IN('1')
ORDER BY `a`.`time` ASC;
只是为了得到一些指标,我开始选择4周的读数,5周等间隔。这些查询完成的执行时间大约在4到5秒之间,随着添加到区间的日数越多,执行时间就会略微增加。然而,突然间执行时间有所跳跃。在'BETWEEN'间隔增加一天几乎将执行时间翻了近20秒。
我之前运行了&查询内解释和结果是我不明白。
随着间隔为BETWEEN "2017-08-18 00:00:00" AND "2017-10-13 23:59:59"
EXPLAIN这个样子的:
+----+-------------+-------+-------+------------------------------+---------+---------+------+--------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+------------------------------+---------+---------+------+--------+-----------------------------+
| 1 | SIMPLE | a | range | PRIMARY,composite3,composite | PRIMARY | 12 | NULL | 542026 | Using where; Using filesort |
+----+-------------+-------+-------+------------------------------+---------+---------+------+--------+-----------------------------+
1 row in set (0.00 sec)
以一天增加这BETWEEN "2017-08-17 00:00:00" AND "2017-10-13 23:59:59"
看起来是这样的:
+----+-------------+-------+------+------------------------------+------+---------+------+---------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+------------------------------+------+---------+------+---------+-----------------------------+
| 1 | SIMPLE | a | ALL | PRIMARY,composite3,composite | NULL | NULL | NULL | 3056618 | Using where; Using filesort |
+----+-------------+-------+------+------------------------------+------+---------+------+---------+-----------------------------+
1 row in set (0.00 sec)
有什么事?为什么它突然不能使用主键/索引,而是搜索必须搜索整个300万个分区的行的子集。在旁注中,间隔的确切位置并不重要。我可以通过提前一个月移动间隔来重新创建此问题。
如果有帮助,在执行时间“跳”之前返回的列是525644,当我加1额外的一天数为535004.
有多少百分比的数据具有质量= 1? –