我有一个非常大的表,其中有近 3 亿条记录。由于 select 查询对我来说太慢了,所以我想将其拆分为大约 800 个小表。
数据集如下所示:
XXXXXX column2 column3 column4 ...
XXXXXX column2 column3 column4 ...
XXXXXX column2 column3 column4 ...
YYYYYY column2 column3 column4 ...
YYYYYY column2 column3 column4 ...
我想根据第一列的值拆分表格(例如记录XXXXXX
分成表XXXXXX
),最快的制作方法是什么?
注意:我已经为其添加了 10 个分区,但它并没有很好地加快速度。
分区在两种情况下作为性能策略起作用:
该表的主查询最终执行表或索引扫描,并且位于具有足够资源和适当配置以执行高级并行性的系统上。因此,如果所有分区都位于同一个物理驱动器上,那不会给您带来太多好处,您会像最初一样受到 I/O 限制。但是,如果您使用的是 16 核系统,并且每个分区都位于物理上不同的磁盘上,该怎么办?分区可能会显着提高系统性能。
分区规则使用在针对该表的最流行查询中经常使用的索引。如果您想通过该途径提高性能,则应根据经常用于过滤或约束结果集的索引值进行分区。最常见的候选者是交易日期,因为报告通常是按日历日期范围进行的。然后,查询优化器可以使用分区规则将操作限制到单个(较小的)分区,或者并行运行两个或多个分区扫描(遵循上述相同的限制)。
我认为想要拆分此表的主要原因是为了性能。但是800个分区?如果您追求的是性能改进,那么这可能是错误的方法。企业数据库在高速缓存中保留尽可能多的顶级表索引以获得良好的性能。在五层 b 树中,对于一个中等使用的表,在第一次访问后,前三层很可能始终保留在缓存中(这对于具有整数主键的 300M 行表来说可能是这样的配置) 。通过将表分成 800 个部分,这意味着将尝试缓存 800 个数据结构(除了表数据本身)。如果您的访问或多或少是按主键均匀分布的,那么在一个分区上进行搜索最终可能会推送其他分区out缓存,最终损害整体性能。
然而,如果您决定这样做,将表分区为 N 个部分的最简单方法是根据您想要的分区数对主键的模数进行分区(primary_key % 800
,在你的情况下)。较新版本的 MySQL 还支持散列分区,使得分区成任意数量的集合相当简单:
PARTITION BY HASH(some_column_value) PARTITIONS number_of_partitions
如果您想将数据放入 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
您可以使用动态 SQL 在您最喜欢的编程语言中循环执行此操作:这可能是最容易呈现的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)