如何使用 AWS 快速对 100 亿行 SQL 表进行分区?
Posted
技术标签:
【中文标题】如何使用 AWS 快速对 100 亿行 SQL 表进行分区?【英文标题】:How to partition 10 billion row SQL tables quickly using AWS? 【发布时间】:2018-06-13 21:22:29 【问题描述】:我有一个以标准化格式交付的 SQL 数据数据库,其中包含几个包含数十亿行数据的表。我决定按 itemId 将大表分区为单独的表,因为当我查询数据时,我一次只关心 1 个项目。在对数据进行分区后,我最终将拥有 5000 多个表。问题是,对数据进行分区大约需要 25 分钟才能为 1 个项目构建单个表。
5000 items x 25 minutes = 86.8 days
完全分区我的整个 SQL 数据库需要 86 多天。我的整个数据库大约 2.5TB。
我可以利用 AWS 在项目级别进行并行化吗?我是否可以使用 AWS 数据库迁移服务以当前形式托管数据库,然后使用 AWS 流程处理所有 5000 个查询,将大表划分为 5000 个较小的表,每个表有 200 万行?
如果不是,我是否只需要投入更多硬件以使其运行得更快(CPU 或 RAM)?
提前致谢。
【问题讨论】:
如果您使用简单的 RDS(诚然,一台合理的机器),正确的索引是否不适用于整个数据集?这听起来有点像XY Problem,因为您提出了解决方案而不是问题。 请说明您的意思。你的“SQL 数据库”是什么,redshift 是什么?(redshift 不会在内部进行分区)如果你使用的是 redshift 频谱/雅典娜,那么你可以将你的数据发布到 s3 存储桶中,但这些数据通常会很大。充实的主要内容是您在尝试什么?用例是什么?数据现在在哪里,您要克服哪些问题? 当前的 SQL 数据库是 SQL Server 2016。用例是从这个表中拉取一个项目的数据需要很长时间,所以我试图将非常大的表逐项划分为许多表因为我总是一次只想要一件东西。当我说很长时间时,我的意思是查询需要几分钟,但如果我想提取这些数据来构建项目的完整历史记录(操作数据),则可能需要数周时间。如果我按项目对其进行分区,则查询将减少到毫秒而不是分钟。但是分区仍然需要很长时间。 更具体地说,我正在查看股票级别的财务数据。我有一个代表公司特征的巨大值表。我有大约 4 万家公司和大约 5000 个特征。此外,该数据库是高度规范化的,因此实际的公司名称和日期在其他表中。我只想一次查看一个特征,因此将大表按特征划分为单独的表会产生 5000 个表,每个表都包含所有公司针对该特定特征的历史数据。 【参考方案1】:这似乎不是一个好策略。一方面,简单的算术运算是 10,000,000,000 行,每个项目 5,000 行导致表中有 2,000,000 个分区。
Redshift 中的限制(默认)是1,000,000 partition per table:
Amazon Redshift Spectrum 在使用 Athena 或 AWS Glue 数据目录:
每个帐户最多 10,000 个数据库。 每个数据库最多 100,000 个表。 每个表最多有 1,000,000 个分区。 每个帐户最多 10,000,000 个分区。
您应该重新考虑您的分区策略。或者您的问题可能不适合 Redshift。可能还有其他更适合您的用例的数据库策略。 (不过,这不是推荐特定软件解决方案的论坛。)
【讨论】:
为了澄清,它将是 5000 个分区,每个分区有 2,000,000 行。 @quantcoder 。 . .您的样本估计值是指 5,000 行,这是该估计值的来源。 对不起,我的意思是 5000 itemID 不是行。单个 itemID 可以引用该表中的数百万行。具体来说,我正在处理公司的财务数据,其中 5000 代表我数据库中的特征数量。我拥有超过 40,000 家公司 20 多年的历史数据。当我在数据库中查询所有公司的单个时间点的单个特征时,这需要很长时间。如果我按特征打破大表,我的查询会显着提高。但是,按特征对表进行分区仍然需要 25 分钟。 @quantcoder 。 . .时间也常用于分区。不过你说的有道理。【参考方案2】:将 itemid 用作 sortkey
和 distkey
。如果表格是vacumm
ed 正确,并且您选择了一个 itemid,这应该会产生良好的结果,其中访问时间几乎与单个表格一样好。 distkey
用于在分片之间分配数据,这意味着每个 itemid 的块将一起存储在同一个分片上,从而更快地检索所有这些块。将 itemid 也设为 sortkey
意味着对于所有存在于同一分片上的小行号的 itemid,在分片上的表块中查找行将尽可能快。
【讨论】:
【参考方案3】:为每个项目创建一个单独的表,该表的所有其他属性都保持不变,这似乎不合逻辑。如果数据格式相同,则将数据保存在同一个表中,除非有特殊问题需要克服。
如果您在 Redshift 表上将 itemId
设置为 SORTKEY
,则 Redshift 将能够跳过不包含所需值的块(使用 WHERE itemId = 'xxx'
时)。这将非常高效。
诚然,试图让这么大的表保持排序对于VACUUM
来说可能太难了。如果没有SORTKEY
,它仍然可以正常工作,因为仍然可以跳过块,但效率不高,因为itemId
的数据将分布在更多块上。
【讨论】:
我试图克服的特殊问题是提取归于一个 itemID 的几行所需的时间。以上是关于如何使用 AWS 快速对 100 亿行 SQL 表进行分区?的主要内容,如果未能解决你的问题,请参考以下文章