(MySQL版本:5.6.15)
我在entity-attribute-value模型中有一个包含10M行的庞大表(Table_A)。 它有一个复合唯一键[Field_A + Element + DataTime]。
CREATE TABLE TABLE_A
(
`Field_A` varchar(5) NOT NULL,
`Element` varchar(5) NOT NULL,
`DataTime` datetime NOT NULL,
`Value` decimal(10,2) DEFAULT NULL,
UNIQUE KEY `A_ELE_TIME` (`Field_A`,`Element`,`DataTime`),
KEY `DATATIME` (`DataTime`),
KEY `ELEID` (`ELEID`),
KEY `ELE_TIME` (`ELEID`,`DataTime`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
将行插入/更新到表每分钟,因此每个[DataTime]的行大小(即每分钟)是常规的,大约3K行。
我有一个"选择"在上面的"插入/更新"之后从该表中查询。 查询在最近25小时内(大约30K行)选择一个指定的元素。此查询通常在3秒内处理。
SELECT
Field_A, Element, DataTime, `Value`
FROM
Table_A
WHERE
Element="XX"
AND DataTime between [time] and [time].
原来的家务管理将在3天后每5分钟删除一行。
为了更好的管理,我尝试每隔6小时在[DataTime]上对表格进行分区。 (当地时间00,06,12,18)
PARTITION BY RANGE (TO_DAYS(DataTime)*100+hour(DataTime))
(PARTITION p2014103112 VALUES LESS THAN (73590212) ENGINE = InnoDB,
...
PARTITION p2014110506 VALUES LESS THAN (73590706) ENGINE = InnoDB,
PARTITION pFuture VALUES LESS THAN MAXVALUE ENGINE = InnoDB)
我的内务处理脚本将删除过期的分区,然后创建一个新分区
ALTER TABLE TABLE_A REORGANIZE PARTITION pFuture INTO (
PARTITION [new_partition_name] VALUES LESS THAN ([bound_value]),
PARTITION pFuture VALUES LESS THAN MAXVALUE
)
新流程似乎运行顺利。
然而,SELECT查询会突然减慢(> 100秒)。
即使所有进程都停止,查询仍然很慢。它不会被修复,直到"分析分区" (读取并存储分区的密钥分发)。
通常每天都会发生。
不会发生在非分区表中。
因此,我们认为它是由分区的MySQL(巨大)表中的索引损坏引起的。
有没有人知道如何解决它?
非常感谢!!
答案 0 :(得分:0)
如果您PARTITION BY RANGE (TO_DAYS(DataTime)*100+hour(DataTime))
,当您使用between [from] and [to]
操作过滤日期时间时,mysql将扫描所有分区,除非[from]
等于[to]
。
因此,您的查询会突然减慢,这是合理的。
我的建议是使用TO_DAYS(DataTime)
分区而不是小时,如果查询最近25小时的数据,它将只扫描最多2个分区。
我不擅长MySql,我无法解释,希望其他聪明人能够进一步解释。但您可以使用EXPLAIN PARTITIONS
来证明这一点。这是Sql Fiddle Demo。