为什么需要跨业务的关联查询
在领域建模中,每个微服务负责某些独立实体的实现。微服务之间可以通过HTTP、RPC进行通信,也可以通过消息队列进行异步通信。由于业务需求,有些场景需要多个实体进行关联查询。
关联查询的场景包括:
- 基于某个维度的数据查询,比如基于终端维度的防火墙日志记录
- 实体之间进行关联查询
对于第一种场景,可以将某个维度相关的数据构造成一张宽表。 对于第二种场景,可以实现了一个聚合服务,负责同步来自业务的数据到同一个数据库中,由聚合服务提供关联查询的能力。
MySQL如何执行关联查询
在MySQL,每个查询都是一次关联。
MySQL关联执行的策略很简单:MySQL对任何关联都执行嵌套循环关联操作,即MySQL先在一个表中循环取出单条数据,然后再嵌套循环到下一个表中寻找匹配的行,依次下去,直到找到所有表中匹配的行为止。然后根据各个表匹配的行,返回查询中需要的各个列。MySQL会尝试在最后一个关联表中找到所有匹配的行,如果最后一个关联表无法找到更多的行以后,MySQL返回到上一层的关联表,看是否能够找到更多的匹配记录,依次类推迭代执行。
优化关联查询的一些技巧:
- 确保ON或者USING子句的列上有索引
- 确保任何的 GROUP BY 和 ORDER BY 中的表达式只涉及到一个表中的列,这样MySQL才有可能使用索引来优化
MySQL基于嵌套关联查询还进行了一些优化:MRR、基于块的嵌套关联查询。
MongoDB如何执行关联查询
MongoDB 通过 $lookup
语法来支持关联查询。$lookup
在同一个数据库中未分片集合上执行左连接,从join后的集合中过滤文档并进行处理。
Elasticsearch如何执行关联查询
Elasticsearch并没有对处理实体之间的关系给出直接的方法。Elasticsearch中进行关系型数据管理的4种常用方法:
- Application-side joins
- Data denormalization:存在部分冗余数据
- Nested objects
- Parent/child relationships
Application-side joins能够与底层的数据存储解耦,具有更好的可扩展性。然而,多次单表查询会增加网络通信开销,导致单次请求的通信响应时间变长。
总结
MySQL的join是在sql解析层执行的,而存储引擎只是进行了基础的数据查询。
要想实现跨业务的关联查询,实际上要做的工作也就是MySQL的join能力在应用层进行实现以及优化。