32

如何优化多表查询的查询性能问题

 3 years ago
source link: https://mp.weixin.qq.com/s?__biz=MzA4NzQwNTM2NQ%3D%3D&%3Bmid=2651055187&%3Bidx=1&%3Bsn=d5a02cb379e35010343410fa06cf86e1&%3Bchksm=8bcea209bcb92b1f23a972a6345693d764fa9d4b24477791d5c105b5c00c6bae46137e647cad&%3Btoken=1039277677&%3Blang=zh_CN
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

在实际开发过程中,使用例如 DDD领 域模型充血方案或者为了数据模型更加的便于之后的拓展和解释,不便于也不建议通过增加状态字段的方式解决问题,但同时上层业务有相对比较复杂,就会存在数据模型与业务要求之间的适配问题,复杂的业务可能体现在数据模型中需要用到多张表的联表查询情况,这类问题如何解决呢?

拆分方式

将原本一条SQL方式,查分为多步。多步可以是在SQL层面也可以是在程序层面。

有些业务情况是允许 通过多条SQL执行 的结果,在程序中进行拼装得到最终符合要求的结果集,在这里作者推荐尽可能在程序中处理,这样做的好处是减少数据库的压力。

也可以 借助其他缓存中间件 ,例如 redis 将一部分数据预先处理好,查询Redis性能肯定比数据库要好。

合并方式(读写分离)

预先将所需要的结果集以冗余方式存储下来,程序只需查询该冗余数据集合即可。

有的人会最先想到使用视图的方式去做,但了解视图的人都知道,每次查询视图数据,仍旧会执行联表SQL,不会起到性能提升效果。

使用 缓存表方式 ,以MySQL为例,MySQL 有提供缓存表的实现,将目标数据先缓存到缓存表中,再查缓存表中数据。

同步数据到ElasticSearch,查询 ElasticSearch 中的冗余数据 ,阿里 Canal 产品提供 MySQL 同步到 ElasticSearch 的实现,可以参考 <1>。但该种方案往往存在延迟的问题,仅适合于对实时性有容忍度的场景中。

大数据 Spark / Flink 方式 ,以实时或者离线方式(实时性要求低)对多张目标表业务处理,持久化结果集,程序只需读取结果集中的数据。Flink 提供 Joining 方案,可以参考 <2>。

分库分表+主从方式 ,例如多租户的场景,租户之间数据隔离,我们可以一主多从,一主用于写数据,多从分别根据租户拆分,各租户查询自己的从库。但该方案在程序实现方面会比较复杂,同时某个租户的数据量非常大还是会存在性能问题。

小结:该类方式往往是通过事件驱动方式实现,就会存在实时性和顺序问题,在选型的时候,需要考虑这方面的问题。以上提到的方案都仅仅适合联表查询相对简单的场景,如果存在子查询之类的复杂要求,就无法满足要求了。

参考内容

  1. https://github.com/alibaba/canal/wiki/Sync-ES

  2. https://ci.apache.org/projects/flink/flink-docs-stable/dev/stream/operators/joining.html


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK