我有一个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)之类的东西创建分区。现在,当我删除时,我将始终删除来自另一个分区的值,而不是我正在阅读或写入的分区。
我是否会遇到此设置的锁定?在我的情况下,分区是否会提高查询速度和可用性?或者我应该寻找另一种解决方案,如果是,那么哪一种?
答案 0 :(得分:3)
从MySQL 5.5开始,您可以使用函数COLUMNS,这简化了对非整数列(例如datetime_utc)的分区。
至于表现:
TRUNCATE TABLE
或rm file
,因此实际上与分区的大小无关。 SELECT
会从partition pruning中受益,因此您只能从符合搜索条件的分区中读取。这也可以加快范围扫描。提示强>
不要忘记添加“默认”分区,例如
PARTITION the_last_one VALUES LESS THAN(MAXVALUE)
以避免INSERT/UPDATE
语句失败,因为没有找到要插入的分区。
答案 1 :(得分:1)
当然,你走在正确的轨道上。您应该在这里创建每日分区并在其中存储数据,您的查询将彻底改变并将像法拉利一样运行。另请参阅本地索引。 还有分区,如果你以前的数据不会干扰,那么你可以保留或删除它不会有太大的区别。实际上,您可以简单地删除分区,而不是删除。这也很快。