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

Posted

技术标签:

【中文标题】MySQL表分区奇怪行为(突然查询慢)【英文标题】:MySQL table partition strange behavior (slow query suddenly) 【发布时间】:2014-11-03 04:19:22 【问题描述】:

mysql 版本:5.6.15)

在实体-属性-值模型中,我有一个包含 1000 万行的巨大表 (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 分钟删除任何行。

为了更好地进行内务管理,我尝试根据 [DataTime] 对表进行分区,每 6 小时一次。 (当地时间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(巨大)表中的索引损坏造成的。

有人知道如何解决吗?

非常感谢!!

【问题讨论】:

你能用EXPLAIN PARTITIONS 发布解释结果吗? Jaugar Chang:EXPLAIN PARTITIONS 将查询所有分区 分区过多会降低查询速度。没有适合您的查询和内务管理的分区解决方案。但是您的查询将比内务处理更频繁地执行。尝试减少分区数以满足查询的需要。顺便说一下,建议你把这个话题迁移到数据库管理员站点,也许你可以在那里得到更好的答案。 感谢您的建议。我已经问过Database Administrators。 【参考方案1】:

如果你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。

【讨论】:

以上是关于MySQL表分区奇怪行为(突然查询慢)的主要内容,如果未能解决你的问题,请参考以下文章

Mysql分区和分表介绍

关于mysql分区与未分区速度和带有主键表分区的问题

Mysql表分区状态查询

十、MySQL表分区

MYSQL 5.7 普通表在线转分区表

MYSQL 5.7 普通表在线转分区表