MySQL表分区奇怪的行为(突然查询慢)

时间:2014-11-03 04:19:22

标签: mysql partition

(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(巨大)表中的索引损坏引起的。

有没有人知道如何解决它?

非常感谢!!

1 个答案:

答案 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