MySQL 分区:分区数量和每个分区的大小之间是否存在性能权衡?

rob*_*ess 10 mysql performance partitioning

我有一个大表(几亿行),我想对其进行有效分区。我的问题是分区大小和分区数之间是否存在权衡。据我所知,分区中使用的列上的大多数查询会更快,因为查询(对于大多数查询)只需要在适用于查询的分区内进行搜索。因此,为了最大限度地提高效率,您应该将大表划分为最大数量的分区,从而使每个分区尽可能小是有道理的。对于 MySQL,这意味着 1024 个分区。但是,拥有大量分区是否有任何性能缺陷?是这样,如何找到最佳分区数?

注意:在 stackoverflow 上已经有一个有点类似的问题,但只有一个答案,(从我的角度来看)没有达到目标。所以我会用我自己的方式陈述这个问题......希望它更清楚

Rol*_*DBA 7

让我们比较它们

分区大小

如果您有以下情况:

  • 一个表中有 1 亿行
  • BTREE 索引
  • BTREE 中的每个 Page 拥有 1024 个键

指标会是什么样子?

由于 LOG(100000000)/LOG(2) = 26.575424759099,每页树节点有 1024 个键的 BTREE 索引的树高仅为 3 (CEILING(LOG(100000000)/LOG(1024)))。只有三个页面节点,在每个访问的树节点中对所需键的二分搜索将导致修剪和隔离大约 30 个键。

分区数

如果您有以下情况:

  • 一个表中有 1 亿行
  • BTREE 索引
  • BTREE 中的每个 Page 拥有 1024 个键
  • 您创建了 1024 个分区

数字会略有不同。

每个分区应该有大约 97656 行。指标现在会变成什么?

由于 LOG(97656)/LOG(2) = 16.575421065795,每页树节点有 1024 个键的 BTREE 索引的树高仅为 2 (CEILING(LOG(97656)/LOG(1024)))。只有两个页面节点,在每个访问的树节点中对所需键的二分搜索将导致修剪和隔离大约 20 个键。

结论

展开键只会删除一个树级别,但实际上会创建 1024 个索引。查询不会知道区别。搜索时间最多可能是名义上的,有利于分区。但是,请确保所有数据都处于活动状态。否则,您可能只访问了几个分区,而其他很少访问数据的分区只占用空间,并且永远不会频繁访问以证明分区的合理性。您可能有不同的性能指标需要担心,这些指标更为明显(例如XFS 中的内部碎片整理、ext3 与 ext4 等)您还需要担心您使用的是哪种存储引擎,因为:

  • 与 MyISAM 相比,InnoDB 索引会有点混乱,因为必须管理聚集索引
  • InnoDB 会在 ibdata1 和当前日志文件(ib_logfile0 或 ib_logfile1)中双重写入数据