PolarDB-X的in常量查询

本文涉及的产品
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
简介: 实际场景中经常需要根据一些常量指标做IN查询,并且IN值往往是分区键。例如在电商场景中,有两张表,买家表与订单表。订单的具体信息会记录到订单表中,该表按照订单ID进行哈希拆分;买家表则会保存买家ID及其关联的订单ID。

场景

实际场景中经常需要根据一些常量指标做IN查询,并且IN值往往是分区键。例如在电商场景中,有两张表,买家表与订单表。订单的具体信息会记录到订单表中,该表按照订单ID进行哈希拆分;买家表则会保存买家ID及其关联的订单ID。一个买家经常需要查询其已购买的所有订单,一种普遍的做法是首先查询买家表获取该买家的所有订单ID,然后根据上述订单ID查询订单的具体信息。假设订单表有4个分片,买家A已下单的订单ID分别为1、 2、4、5和9,那么便会产生如下的SQL,即包含5个值的IN条件查询。

逻辑sql: select * from order where order_id in (1, 2, 4, 5, 9);

执行方式

不同于MySQL,PolarDB-X的架构可以分为计算层和存储层,存储层的DN 节点(数据节点)保存所有的数据。更多背景信息可以参考专栏文章 PolarDB-X 简介。

b1.jpg

那么计算节点在收到这条逻辑SQL后,如何从DN节点拉取数据并进行计算呢?

Naive的执行方式

下发至所有分片的物理SQL中均包含所有的in值,如下所示。这种naive的执行方式会带来两个问题,一是随着订单表分片数的增多,需要扫描的分片数急剧增加,而该买家订单数据所在的分片数并未增加;二是随着in值的增多,下发的物理SQL在执行时会由索引扫描变为全表扫描,以上两个原因使得RT急剧升高。

分片1 物理sql: select * from order_01 where order_id in (1, 2, 4, 5, 9);
分片2 物理sql: select * from order_02 where order_id in (1, 2, 4, 5, 9);
分片3 物理sql: select * from order_03 where order_id in (1, 2, 4, 5, 9);
分片4 物理sql: select * from order_04 where order_id in (1, 2, 4, 5, 9);

基于动态裁剪的执行

由上述讨论可知,我们希望可以裁剪掉一定不包含所需数据的分片,由于in字段即为分区键,因此我们可以使用分区算法计算每个in值所属分区,如下所示。

hash(1) = 1, hash(2) = 2, hash(4) = 4, hash(5) = 1, hash(9) = 1

以上述例子为例,显然我们无需向分片3下发物理SQL。进一步地,因为分片1只可能包含订单ID为1、5和9的数据,而不可能包含订单ID为2或4的数据,于是我们可以进一步对物理SQL中包含的in值进行裁剪。

现在我们知道了需要下发的SQL涉及三个分片,那么如何下发这三条物理SQL呢,或者说下发SQL并等待结果的并行度是多少呢?显然,有两种极端,一是全部串行,该方式执行效率极低;二是全部并行,同时起有效分片数个线程向各个分片发送所有物理SQL,该方式的问题是如果分片数太多,会给系统带来非常大的压力,同时会有大量的线程上下文切换。综合考虑,我们默认将下发物理SQL的并行度设置为机器的CPU核数,使用类似滑动窗口的方式下发物理SQL。

此外,我们希望下发到每个分片的物理SQL中包含的in值不要太多,否则该SQL在DN节点执行时很有可能进行全表扫描而非预期的索引扫描。因此当in值较多时,我们会对in值进行切割,分批下发,执行流程如下图所示。
b1.jpg

仍然以上述的例子为例,假设我们的CN节点只有两个核,假设每次下发的物理SQL中的in值不超过两个(当然实际中不会设置的这么小),那么我们会共计下发四条物理SQL,如下所示,其会被划分为两个批次,也就是说计算节点和数据节点需要有两次网络交互。试想一下,如果我们下发的物理SQL只有两条时,那么我们便可以在一个批次中完成所有物理SQL的下发,此时计算节点和数据节点只有一次网络交互。因此,当用户对于RT要求较高时,我们建议in值数量应当较少,以保证其涉及的分片数不超过CPU核数且每个分片只会下发一条物理SQL。

//第一次下发了两条物理sql
分片1 物理sql-1: select * from order_01 where order_id in (1, 5);
分片2 物理sql: select * from order_02 where order_id in (2);
//第二次下发了两条物理sql
分片1 物理sql-2: select * from order_01 where order_id in (9);
分片4 物理sql: select * from order_04 where order_id in (4);

in值数量不固定带来的挑战

为了加速SQL的执行,我们会对参数化SQL的执行计划进行缓存,而业务代码中的in值数量有时并不相同,这会使得执行计划的缓存空间可能会被仅是in值数量不同的SQL占满,导致其他SQL的执行计划失效。解决这个问题的思路也比较简单,我们会用一个问号来替代in的列表,从而避免上述情况的发生。

测试

我们在规格为2×16C64G的节点上,针对一张分表数为64,分表记录数为百万的表在不同in值数量、不同并发下进行了测试,分区方式为哈希分区,测试结果如下。

测试场景1-1

不同并发,不同in值数量,开启IN查询动态裁剪能力,查看RT变化。
c1.jpg

测试场景1-2

不同并发,不同in值数量,关闭IN查询动态裁剪能力,查看RT变化。
c2.jpg

测试场景2-1

不同并发,不同in值数量,开启IN查询动态裁剪能力,查看吞吐变化。
c3.jpg

测试场景2-2

不同并发,不同in值数量,关闭IN查询动态裁剪能力,查看吞吐变化。
c4.jpg

测试结论

● 开启IN查询的动态裁剪能力后,吞吐和RT都有明显的改善。
● 对于RT比较敏感的客户,建议in值数量不要取的太多。

总结

本篇首先介绍了in查询的一个经典应用场景,接着分析了分布式数据库中执行in查询sql时naive的执行方式,其执行效率非常低下。为了提高执行效率,我们进行了分区裁剪与in值裁剪。进一步地,考虑到物理SQL中的in值太多会使得存储节点在执行物理SQL时有更大的可能进行全表扫描而非预期的索引扫描,因此当一个分片涉及的in值较多时,我们会将in值进行分割,分批次下发in查询。为了防止并发量过大给系统带来巨大的压力,下发物理SQL的默认并发度为机器CPU核数。此外,我们还针对in值数量不同可能导致计划缓存失效的问题进行了优化。最后,我们测试了打开与关闭in查询动态裁剪的情况下,吞吐量与延迟的变化,测试结果表明开启IN查询的动态裁剪能力后,吞吐和RT都有明显的改善。此外,我们建议对于RT比较敏感的客户,in值数量不要取的太多。

本文作者:越寒
更多好文,欢迎关注PolarDB-X知乎号

相关实践学习
快速体验PolarDB开源数据库
本实验环境已内置PostgreSQL数据库以及PolarDB开源数据库:PolarDB PostgreSQL版和PolarDB分布式版,支持一键拉起使用,方便各位开发者学习使用。
相关文章
|
3月前
|
存储 关系型数据库 分布式数据库
PolarDB 并行查询问题之分布式查询执行过程中的数据分发如何解决
PolarDB 并行查询问题之分布式查询执行过程中的数据分发如何解决
47 1
|
3月前
|
关系型数据库 MySQL 分布式数据库
PolarDB 并行查询问题之大数据量的实时分析查询挑战如何解决
PolarDB 并行查询问题之大数据量的实时分析查询挑战如何解决
36 2
|
3月前
|
关系型数据库 MySQL 分布式数据库
PolarDB 并行查询问题之处理类似JOIN和GROUP BY的复杂查询如何解决
PolarDB 并行查询问题之处理类似JOIN和GROUP BY的复杂查询如何解决
25 1
|
3月前
|
关系型数据库 MySQL 分布式数据库
PolarDB 并行查询问题之帮助处理实时性分析查询如何解决
PolarDB 并行查询问题之帮助处理实时性分析查询如何解决
40 1
|
3月前
|
关系型数据库 MySQL 分布式数据库
PolarDB 并行查询问题之提升对复杂查询的处理能力如何解决
PolarDB 并行查询问题之提升对复杂查询的处理能力如何解决
24 1
|
3月前
|
存储 SQL 运维
“震撼发布!PolarDB-X:云原生分布式数据库巨擘,超高并发、海量存储、复杂查询,一网打尽!错过等哭!”
【8月更文挑战第7天】PolarDB-X 是面向超高并发、海量存储和复杂查询场景设计的云原生分布式数据库系统
110 1
|
4月前
|
关系型数据库 MySQL 分布式数据库
PolarDB产品使用问题之查询数据库时出现报错,是什么原因
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
|
4月前
|
存储 运维 关系型数据库
PolarDB产品使用问题之在删除主节点上的表后尝试查询归档表遇到问题,该如何解决
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
|
4月前
|
SQL 关系型数据库 MySQL
PolarDB产品使用问题之搜索和查询冷数据如何照时间范围进行查询
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
|
6月前
|
关系型数据库 分布式数据库 数据库
【PolarDB开源】PolarDB-X源码解读:分布式事务处理机制揭秘
【5月更文挑战第20天】PolarDB-X,PolarDB家族的一员,专注于大规模分布式事务处理,采用2PC协议保证ACID特性。源码解析揭示其通过预提交、一致性快照隔离和乐观锁优化事务性能,以及利用事务日志进行故障恢复。深入理解其事务处理机制对开发者掌握分布式数据库核心技术至关重要。随着开源社区的发展,更多优化方案将涌现,助力构建更强大的分布式数据库系统。
221 6

热门文章

最新文章

相关产品

  • 云原生数据库 PolarDB