关于数据库多表查询的一次优化

本文探讨了在项目中遇到的长时间查询问题,通过实例分析了等值连接导致的错误,并揭示了主键和索引在内连接中的重要性。通过给非聚簇索引添加索引,查询性能提升4倍,揭示了如何正确使用LEFT JOIN和理解数据库查询优化原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        在项目中的某个查询由于设计了多表查询,前端发送的某个接口到收到数据经历了很长时间,所以决定来优化一下这个查询。

        首先一张驱动表students表有2000多条数据

       被驱动表course有5800条数据左右

       下面students和course表的简称分别为p和pic,

        首先,我们尝试了一下where后面条件的等值连接

结果出乎我们的意料,结果是不对的,少了很多数据。        

        我们的结果是要求所有的学生记录都需要,但是由于等值连接(内连接)的过程,所以出错了。

        一方面,由于数据库对于这种没有主表要求的具体sql来说,是会有它自己的优化过程,它会选取一个最优的查询结果。 那就把我们认为是被驱动表的表当成驱动表也就是主表在使用了,因为我们的p表的p_id是主键,它是有聚簇索引的,对于聚簇索引,其本质上就是一颗b+树,可以根据具体的值快速找到所需要的数据,聚簇索引与非聚簇索引的区别在于是否需要所谓的“回表”的过程,所以数据库就出现了以p表为被驱动表的样子,使得结果不是需要的结果。

        另一方面,对于上面这条sql来说,p表的主键是p_id,而pic表的主键是pc_id,除了聚簇索引外两表再无其它索引,where可能就会出现错误的结果,如果pic表表的某些数据没有对应的p表数据 那么结果中不出现,如果p表中的数据没有在pic表中对应出现 那么结果中也不会出现内连接(Inner join  on)和等值连接(where ) 其实是一样的。

        对于这个sql我们应该让p表进行 left join表pic表

 对于这个没有索引的sql,且sql明确指出p表为主表,其查询过程如上图所示,其实是对p表进行 nested loop join,拿着p表的每一条数据进行与pic表的每一条数据进行比对,如果join的表的对应字段没有索引,那么就会出现被驱动表全表扫描的过程,这个时间的开销是很大的。

 接下来我们给pic表的p_id加入索引后,这个索引是普通索引,也就是非聚簇索引,会有回表的过程,

 加入索引后的时间下降了4倍多一些。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值