MySQL:将大表拆分成小表的最快方法

MrR*_*ROY 3 mysql

我有一张非常大的桌子,有近3亿张唱片.由于select查询对我来说太慢了,我想把它拆分成大约800个小表.

数据集如下所示:

XXXXXX column2 column3 column4 ...
XXXXXX column2 column3 column4 ...
XXXXXX column2 column3 column4 ...
YYYYYY column2 column3 column4 ...
YYYYYY column2 column3 column4 ...
Run Code Online (Sandbox Code Playgroud)

我想根据第一列的值拆分表(例如,XXXXXX将拆分记录到表中XXXXXX),最快的方法是什么?

注意:我已经为它添加了10个分区,但它并没有很好地加速它.

Cur*_*urt 10

在两种情况下,分区可用作性能策略:

  1. 该表的主要查询最终执行表或索引扫描,并且位于具有足够资源和适当配置的系统上,以实现高水平的并行性.因此,如果所有分区都在同一个物理驱动器上,那对你来说并没有多大帮助,那么就像你在第一时间那样绑定I/O. 但是,如果您使用的是16核系统,并且每个分区位于物理上不同的磁盘上?分区可能会对系统性能产生惊人的改进.

  2. 分区规则使用的索引通常用于针对该表的最流行的查询.如果您要通过该路由获得性能,则应该对通常用于过滤或约束结果集的索引值进行分区.最常见的候选者是交易日期,因为报告通常是日历日期范围.然后,查询优化器可以使用分区规则来限制对单个(较小)分区的操作,或者并行运行两个或多个分区扫描(受上面提到的相同限制).

我假设想要拆分此表的主要原因是为了提高性能.但800分区?如果您正在追求性能提升,那可能是错误的方法.企业数据库在缓存内存中保留尽可能多的顶级表索引,以获得良好的性能.在五级b树中,对于中等使用的表,在第一次访问后,前三个级别很可能始终保存在缓存中(这可能是具有整数主键的300M行表的配置) .通过将表拆分为800个,这意味着将有800个数据结构试图保持缓存(除了表数据本身).如果您的访问权限或多或少地均由主键分布,那么在一个分区上搜索将最终将其他分区 缓存中推出,最终会损害整体性能.

尽管如此,如果您决定这样做,将表分成N个部分的最简单方法是按照您希望针对主键的分区数量(primary_key % 800在您的情况下)对其进行分区.较新版本的MySQL也具有散列分区支持,使分区成任意数量的集合相当明确:

PARTITION BY HASH(some_column_value) PARTITIONS number_of_partitions
Run Code Online (Sandbox Code Playgroud)

如果你想将你的数据放到800个实际的表中,你将不得不这样做编辑魔术,或者使用脚本语言,并在SQL中执行:

CREATE TABLE table1 LIKE MasterTable
CREATE TABLE table2 LIKE MasterTable
CREATE TABLE table3 LIKE MasterTable
..
INSERT INTO table1 SELECT * FROM MasterTable WHERE id MOD 800 = 0
INSERT INTO table2 SELECT * FROM MasterTable WHERE id MOD 800 = 1
INSERT INTO table3 SELECT * FROM MasterTable WHERE id MOD 800 = 2
Run Code Online (Sandbox Code Playgroud)

您可以使用动态SQL在您喜欢的编程语言的循环中执行此操作:这可能是最容易呈现的.