使用MySQL分区来加速并发删除和选择?

时间:2013-09-24 15:43:53

标签: mysql sql performance partitioning

我有一个MySQL Innodb表,其中包含大约850万行。表结构基本上如下所示:

CREATE TABLE `mydatatable` (
  `ext_data_id` int(10) unsigned NOT NULL,
  `datetime_utc` date NOT NULL DEFAULT '0000-00-00',
  `type` varchar(8) NOT NULL DEFAULT '',
  `value` decimal(6,2) DEFAULT NULL,
  PRIMARY KEY (`ext_data_id`,`datetime_utc`,`type`),
  KEY `datetime_utc` (`datetime_utc`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

每晚,我使用以下查询从此表中删除过期的值:

delete from mydatatable where datetime_utc < '2013-09-23'

此查询似乎不使用indizes,运行需要相当长的时间。但是,我也在同一个表上获得并发更新和选择。然后这些被锁定,导致我的网站在那时没有响应。

我正在寻找各种方法来加快这种设置。我突然想到MySQL分区,我想知道这是否合适。我总是在此表中添加并选择较新的数据并删除旧数据。我可以基于MOD(DAYOFYEAR(datetime),4)之类的东西创建分区。现在,当我删除时,我将始终删除来自另一个分区的值,而不是我正在阅读或写入的分区。

我是否会遇到此设置的锁定?在我的情况下,分区是否会提高查询速度和可用性?或者我应该寻找另一种解决方案,如果是,那么哪一种?

2 个答案:

答案 0 :(得分:3)

从MySQL 5.5开始,您可以使用函数COLUMNS,这简化了对非整数列(例如datetime_utc)的分区。

至于表现:

  • 删除分区是LIST和RANGE分区的恒定时间操作。速度相当于TRUNCATE TABLErm file,因此实际上与分区的大小无关。
  • 对分区表执行SELECT会从partition pruning中受益,因此您只能从符合搜索条件的分区中读取。这也可以加快范围扫描。

提示

不要忘记添加“默认”分区,例如

    PARTITION the_last_one VALUES LESS THAN(MAXVALUE)

以避免INSERT/UPDATE语句失败,因为没有找到要插入的分区。

答案 1 :(得分:1)

当然,你走在正确的轨道上。您应该在这里创建每日分区并在其中存储数据,您的查询将彻底改变并将像法拉利一样运行。另请参阅本地索引。 还有分区,如果你以前的数据不会干扰,那么你可以保留或删除它不会有太大的区别。实际上,您可以简单地删除分区,而不是删除。这也很快。