乐趣区

关于mysql:如何实现高效联表查询

本地缓存

缓存作为进步性能一种可选形式最先被思考,其具备简略、易用、高效的个性。在联合 Java8 之后的新个性 Lambda 表达式,能够轻松实现相似 Join、Groupby、Sort 操作。

这个形式也是我首选的解决形式。其本质是将本来数据库解决压力转嫁到服务器内存中,鉴于当初绝大多数公司都是分布式架构,服务性能相比单体架构有显著的晋升,反观,MySQL 在分布式时代经常成为性能的瓶颈,从而衍生出 TiDB 这类分布式数据库。

但缓存形式存在显著的短板—不适宜大数据量操作,容易导致 Out Of Memory。但我有一个大胆,其实也称不上大胆想法,咱们是不是能够实现 Spark SQL 一样在内存中构建表构造,处理表相干操作呢?如果有机会的话,再跟大家进行分享。

冗余

退而求其次,冗余也是经常被采纳的形式,但其往往存在实时性和准确性的问题,因此只适宜容许不精准和对变动宽容的场景。从实质来说,我认为冗余也是缓存的一种实现形式,如果这个问题,不局限于本身数据库去实现冗余,咱们能够尝试应用 Redis 实现实时性的冗余,把所有服务都须要的用户手机号码信息放到 Redis 中,其余服务通过间接调用 Redis 获取数据,或者用户核心提供一系列查问 API 供其余业务线服务应用。而且 Github 上存在一个 rediSQL 开源我的项目,反对 Redis 数据通过 SQL 形式实现数据查问,当初曾经孵化成为 zeeSQL,这样是不是能够更加 Think Big 了呢。

Join 查问

尽管本文曾经应用大量的篇幅表明不违心在数据库层面解决 Join 查问,但还是存在大量场景选用数据库 Join 操作才是比较简单高效的形式。因此,当不得不抉择该种形式时,咱们又有哪些进步查问性能的形式呢?

很多时候不是产品不够好,而是应用的人不会用。Join 查问也是一样,如果从实现原理理解,从根上对其有深刻的理解,能力施展其真正的作用。上面是我的一些摘记,与大家分享:

本文以 Left Join 作为示例阐明,其余 Join 相似。

前提:

  1. 被 Join 表 关联字段须要存在索引
  2. 两表的关联字段须要编码格局一样,否则索引会生效

优化:

  1. 依据理论状况抉择适合的 Join 算法(NLJ 和 BNL)
  2. 尽量应用 hash join(8.0.18)
  3. 依据业务场景抉择 Join 类型,尽可能抉择 Join,而防止应用 Left Join、Right Join、Full Join
  4. 关联条件存在 NULL 状况,在 where 语句中增加排除为空的条件
  5. 不应用子查问
  6. 结合实际业务场景抉择适合 Join 计划

答疑:

Left Join 与 Join 原理区别

Join 以两张表中的数据量小的那张表作为根底表,根据关联条件,查问另一张表。Left Join 以右边那张表作为根底表,进行查问,往往右边那表是大表,所以 Join 查问要比 Left Join 性能好。

NLJ 和 BNL 原理

  • 嵌套循环连贯 Nested-Loop Join(NLJ) 算法:

实用于关联的两个字段都为索引的状况下,首先会查问出全副驱动表的关联字段,而后一一去和被驱动表关联,直至全副关联实现。

  • 基于块的嵌套循环连贯 Block Nested-Loop Join(BNL) 算法:

如果关联字段不是索引或者有一个字段不是索引,MySQL 则会采纳此算法,和 NLJ 不同的是,BNL 算法会多加一个 join_buffer 缓存块,关联时会把驱动表的局部数据放入到缓存块中,而后用被驱动表一一比照,直至查问实现。然而这个 join_buffer 缓存块是无序的,所以查问比照的次数会很多。

如何通晓以后查问属于哪种 Join 算法

至于一条 SQL 语句应用什么算法去做的关联操作,应用 EXPLAIN 命令能够查看,上面为嵌套循环连贯算法:

基于块的嵌套循环连贯 Block Nested-Loop Join(BNL) 算法:

拓展浏览:

  • mysql 如何优化 left join – 云 + 社区 – 腾讯云
  • 技术分享 | MySQL 优化:JOIN 优化实际 – 知乎
  • https://blog.csdn.net/xianyun…
退出移动版