我们使用机器学习技术将英文博客翻译为简体中文。您可以点击导航栏中的“中文(简体)”切换到英文版本。
将批量操作从 Oracle 迁移到 PostgreSQL 时的关键注意事项
亚马逊云科技 推出了
在 Oracle 中实现批量数据操作
SQL 是一种声明式数据库查询语言,而不是编程语言。但是,诸如Oracle的PL/SQL之类的数据库过程语言是编程语言,它们嵌入SQL语句以扩展其功能,这是有代价的。当 Oracle 的过程语言引擎 (PL/SQL) 处理代码块时,它会在自己的引擎中运行原生的过程语句,但是当遇到 SQL 语句时,它会将语句传递给 SQL 引擎。SQL 引擎运行 SQL 语句并将结果返回到过程语言引擎。这两个引擎之间的这种来回控制权转移被称为 上下文切换 ,它会带来一定的性能开销,并且在发生许多上下文切换时可能会导致性能急剧下降。为了缓解这种担忧,Oracle 通过将上下文切换组合在一起的功能来增强其程序语言。PL/SQL 中的 BULK COLLECT 和 FORALL 语句就是这些增强功能的示例。BULK COLLECT SELECT 语句通过一次读取即可检索多行,从而提高了批量数据检索的速度:
同样,PL/SQL 提供了一个 FORALL 语句,该语句使用集合批量更改行,而不是一次将更改应用于一行:
在本文的其余部分中,我们将使用示例用例来解释如何进行批量数据操作。该用例从包含超过 1000 万条记录的订单表中提取订单,如果订单价格大于 10,000 美元,则提供 1,000 美元的折扣,并将折扣订单插入折扣订单目标表。订单表中大约 95% 的记录定价超过 10,000 美元。
Orders (primary key ID) | |
Name | Type |
ID | NUMBER (8) |
Name | VARCHAR (100) |
Price | NUMBER (6,2) |
Discounted_Orders (primary key ID) | |
Name | Type |
ID | NUMBER (8) |
Name | VARCHAR (100) |
Price | NUMBER (6,2) |
我们可以使用 BULK COLLECT、FETCH 和 FORALL 语句在 Oracle 的 PL/SQL 中实现这个用例,如以下代码片段所示:
在 PostgreSQL 中实现批量数据操作
PostgreSQL 的 PL/pgSQL 没有等同于甲骨文 PL/SQL 功能的内置功能,例如批量收集、提取或 FORALL。但是,您可以从多种方法中进行选择,以实现相似的功能。在本节中,我们比较了四种这样的方法。这包括将过程数据库平台特定语言和声明式 SQL 语句组合使用为纯 SQL 语言。这些方法之间的权衡因性能影响和处理记录的灵活性而异。
1。循环浏览 SELECT 语句的结果
在这种方法中,我们将所有价格大于10,000美元的订单选择到游标中,循环地从光标中提取每一行并应用1,000美元的折扣,然后将记录插入目标表。在这里,上下文切换发生的次数与价格大于 10,000 美元的订单的次数一样多。参见以下代码:
2。使用 PostgreSQL 函数(ARRAY_AGG 和 UNNEST)
与以前的方法相比,这种方法极大地减少了上下文切换的次数。这种方法的缺点是,ARRAY_AGG 和 UNNEST 操作可能无法为超大型数据集提供最佳性能。
3。仅使用 SQL 语句
在这种方法中,我们使用纯 SQL 语句编写整个代码,并完全绕过过程语言引擎。这消除了在过程语言引擎和 SQL 引擎运行之间进行上下文切换的需要,如以下代码片段所示:
4。将 SQL 语句用于分块的大批处理
在某些情况下,由于资源限制(例如,处理内存限制或结果集分页)等原因,纯 SQL 语句不适用于大批量记录。在这些情况下,我们可以使用 LIMIT 子句来计算以较小的增量对大批记录进行分块所需的偏移量,如以下代码片段所示:
比较技巧
我们可以按照从最少使用的上下文切换到大多数的顺序对这些批量操作技术进行排序:
- 使用纯 SQL 语句(如果可行)
- 将 SQL 语句用于分块的大批处理
- 如果上述方法不可行,请使用 AGG_ARRAY 和 UNNEST
- 将 SQL 语句的结果缓存在游标中并逐行处理结果
尽管减少上下文切换的数量可以帮助提高查询性能,但在评估所选方法的整体性能时,您需要考虑其他标准,例如资源限制、并行化和系统配置。为了证明这一点,Amazon DMA 使用包含 1000 万条记录的订单表对上述技术进行了性能基准分析,并观察到第四个选项的运行时间最短,并且比最慢的第一个选项快 300% 以上。下表列出了详细信息。
Options | Relative runtime to Option 4 (smaller is faster) | |
1 | LOOP through the results of a SELECT statement | 3.24X |
2 | Use PostgreSQL functions (ARRAY_AGG and UNNEST) | 1.4X |
3 | Use only SQL statements | 1.12X |
4 | Use SQL statements with chunked large batches | 1X |
根据性能基准分析,我们按以下顺序对该方法进行了排名:
- 使用纯 SQL 语句(如果可行)
- 对分块的大批次使用 SQL 语句(如果我们需要将大批次分块成较小的增量)
- 使用 PostgreSQL 函数(如果纯 SQL 不可行,则使用 ARRAY_AGG 和 UNNEST)
- 循环浏览 SELECT 语句的结果(作为最后的手段,在游标中缓存 SQL 语句的结果并逐行处理结果)。
结论
在这篇文章中,我们分享了亚马逊 DMA 对适用于 PostgreSQL 的亚马逊 RDS 或亚马逊 Aurora PostgreSQL 兼容版的批量操作的关键注意事项。
Amazon DMA 提供补充咨询服务以制定迁移策略和实施计划,并使您的内部迁移团队(或亚马逊专业服务或 APN 合作伙伴,如果有)能够进行迁移实施。如果您计划将工作负载迁移到 亚马逊云科技 数据库和分析服务,
在接下来的几周内,我们将发布更多关于如何处理 PostgreSQL 中的大型对象、如何在 PostgreSQL 分区之间强制实现唯一性等的文章。敬请期待!
作者简介
Ezat Karimi 是亚马逊网络服务 (亚马逊云科技) 的高级解决方案架构师。她是数据库迁移加速器 (DMA) 团队的成员,负责帮助客户完成数据库应用程序现代化之旅。
*前述特定亚马逊云科技生成式人工智能相关的服务仅在亚马逊云科技海外区域可用,亚马逊云科技中国仅为帮助您发展海外业务和/或了解行业前沿技术选择推荐该服务。