Oracle DB Sequence 并行处理 — 多线程

Oracle DB Sequence Parallel processing - Multi threading

提问人:Dk Vishnu 提问时间:9/22/2022 更新时间:9/22/2022 访问量:303

问:

在创建新对象时,我需要生成一个唯一的编号以将其附加到对象的元数据中。对象元数据只需使用框架库从代码中设置,因为对象在内部链接到数据库中的多个表,不建议直接更新列,并且有风险。为此,我尝试使用 Oracle DB 序列并使用 nextval 作为唯一参考编号。但是为了使这个序列生成更加并行,我想引入 10 个序列器,增量为 10,分别以 1、2、3..、10 开头,这样就不会有序列产生重复的数字。这个想法是,当一次创建 10000 个对象时,我可以将负载拆分为 10 个不同的序列,并并行处理 10 个批次。

但是当我实现这个解决方案时,我可以观察到单个序列实现比分成 10 个不同的序列更有效。

观察结果是这样的。

案例一:

从单个定序器生成 10 个序列(来自同一定序器的 10 个序列号)- ~400 ms

从 10 个独立的测序仪生成 10 个序列(每个测序仪 1 个) - ~40 ms

案例二:

从单个定序器生成 1000 个序列(来自同一定序器的 1000 个序列号)- ~4600 ms

从 10 个独立的测序仪生成 1000 个序列(每个测序仪有 100 个数字) - ~4200 ms

因此,随着并行请求的增加,单个序列虽然看起来慢了十倍,但它的性能更好,而多序列实现线性扩展了 100 倍,并且花费的时间几乎与单个序列相同的时间生成了 1000 个序列。

此处所有 Sequencer 的缓存大小相同,并设置为 100。

我想了解,多音序器实现是否像我想象的那样有助于并行处理?如果没有,请解释原因?如果可以,那么我在哪里错误地实施了它?

提前非常感谢您抽出时间参加这次:)

数据库 Oracle 并行处理 序列 NextVal

评论


答:

0赞 pmdba 9/22/2022 #1

您的解决方案似乎不必要地复杂。只需增加一个序列的缓存大小,使其在单个突发中至少包含您可能需要的值。

查询多个序列会给数据库内核带来更多的开销,因为每个序列及其缓存都必须在内存中加载和维护,每个查询都必须单独解析和运行,并且对不同对象的这些单独查询将消耗更多的库缓存。这比编译一个查询并使用适当调整的缓存执行更多次要昂贵得多。最终,它会导致资源争用而不是扩展,我不建议走这条路。

评论

0赞 Dk Vishnu 9/22/2022
谢谢@pmdba。是否有任何甜蜜的数字可以建议,例如 2 个音序器或 3 个。这将有助于并行处理吗?预计一次将创建多个 10000 个对象。因此,即使缓存为 10000,它也可能没有多大帮助。
0赞 pmdba 9/22/2022
只有一个序列。调整缓存。多个序列将导致不必要的计算开销和资源争用。
0赞 Dk Vishnu 9/22/2022
我明白了。我将单独使用单个序列来满足我的需要。但我真的很难理解和掌握数据库端后台实际发生的事情。我正在四处寻找文章,但找不到我能理解的东西。您能否解释一下为什么我们在执行 10 个不同的独立查询时无法获得任何时间?
0赞 Dk Vishnu 9/22/2022
据我了解。情况 1:多次执行 1 个查询。解析/编译需要 x 秒 执行需要 y 秒 加载和更新缓存需要 z 秒 所以总时间是 x+y+z 秒
0赞 Dk Vishnu 9/22/2022
案例 2:多次执行 10 个不同的查询。即使它是一个不同的查询,每个查询所消耗的时间也应该与案例 1 几乎相同。即,解析/编译需要 x 秒,执行需要 y 秒,加载和更新缓存需要 z 秒