Mysql对索引的分区效果

问题描述 投票:0回答:1

我有多个业务数据大表,最小的一个表有3800万行(24G数据,26G索引大小)。我有索引设置,以加快查找和缓冲池设置为总RAM的80%(116G)。即使经过这些设置,随着时间的推移,我们也开始观察性能问题。我对磁盘大小(1T)有约束,并且当前不提供分片。数据增长每天增加到0.5M行。这导致频繁的优化和主开关练习。表模式和索引已经过优化。因此,我已经开始考虑对表进行分区以提高性能。我的主要分区用例是通过删除分区来按月删除数据,以便不需要优化并改进读/写延迟。以下是其中一个大表的结构(由于法律原因,列名已被更改 - 假设索引定义的列具有查找用例):

   CREATE TABLE `table_name` (
     `id` int(11) NOT NULL AUTO_INCREMENT,
     `data_1` int(11) NOT NULL,
     `data_2` varchar(40) COLLATE utf8_unicode_ci NOT NULL,
     `data_3` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
     `data_4` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL,
     `created_at` datetime DEFAULT NULL,
     `updated_at` datetime DEFAULT NULL,
     PRIMARY KEY (`id`),
     KEY `index_data1` (`data_1`),
     KEY `index_data2` (`data_2`)
   ) ENGINE=InnoDB AUTO_INCREMENT=100572 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

我打算在created_at列上进行分区。但是,问题是分区列必须是所有唯一键的一部分。我可以将created_at列添加到主键,但这会导致索引大小增加,而后者又有自己的副作用。有一些解决方法或更好的解决方案吗?

除了解决这个问题之外,还有更多的问题,其答案在任何文档或文章中都找不到。 1.为什么mysql保证分区列成为唯一键的一部分? 2.来自ORM的查询没有created_at子句,这意味着无法使用我们可以使用的读取进行修剪,并且提供的插入始终被修剪。但是,看起来并非如此。为什么mysql打开所有插入分区?

Mysql版本 - 5.6.33-79.0-log Percona Server(GPL),版本79.0,修订版2084bdb

mysql database database-performance partitioning
1个回答
1
投票

qazxsw poi比qazxsw poi只占用更多的空间。我估计你的数据远低于1%。我无法分辨索引空间 - 你能告诉我们非主要索引吗?

说明:数据的叶节点(由PK组织的BTree)的大小不会改变。非叶子节点将PRIMARY KEY(id, created_at)添加到每个“行”。作为InnoDB的经验法则,非叶节点占据了BTree的大约1%的空间。

对于PRIMARY KEY(id) BTrees,除非created_at已经在索引中,否则叶节点需要额外的4个字节/行用于INDEX

假设你现在有created_at,其中created_atINDEX(foo)foo也是INT。这总共是8个字节(加上开销)。添加id(一个4字节的INT)将每个叶子'row'扩展到12 +开销。因此,该指数的规模可能会翻倍。

猜测:你的24G + 26G可能会增长到25G + 33G。

听起来你有几个索引。你明白,如果你也有created_atTIMESTAMP没用吗?在某些情况下,INDEX(a)INDEX(a,b)好多了?我们来讨论你的索引。

INDEX(x,y)的主要好处是你的用例 - INDEX(x), INDEX(y)PARTITIONing快很多。我的DROP PARTITION就这样了。

不要被分区所迷惑。您希望“读/写延迟得到改善”;这种情况不太可能发生。如果您想进一步解释,请提供您认为可能发生的DELETE

您将分区多少个“月”?我建议不要超过50.当有很多分区时,blog会有一些效率低下的问题。

由于需要将分区键置于SELECT键中,因此唯一性约束几乎完全无用。将它放在PARTITIONing id的末尾不是问题。

考虑UNIQUE以外的东西是否可以成为PK。

问题1:当AUTO_INCREMENT连续时,所有id键都会立即检查“dup key”。如果没有分区键是唯一键的一部分,这将意味着探测每个分区。这太昂贵了,无法考虑;所以没有完成。 (将来,可以实现'全局到表'的INSERTing密钥。版本8.0有一些钩子。)

问题2a:是的,如果UNIQUE UNIQUE没有充分指定分区键,则将打开并查看所有分区。这是最小化分区数量的另一个原因。嗯...如果你在本月31日做SELECT's并且第二天做同样的WHERE,你可以减少行数(即使没有任何删除,只有SELECT);这似乎是“错误的”。

问题2b:“为什么mysql打开插入的所有分区?” - 你认为它的作用是什么?有一个奇怪的情况,“第一个”分区被“不必要地”打开 - 分区键是SELECT

© www.soinside.com 2019 - 2024. All rights reserved.