SQL 算法 : 浅谈数据库Join的实现原理

Join的实现算法有三种,分别是Nested Loops Join, Merge Join, Hash Join。

DB2、SQL Server和Oracle都是使用这三种方式,不过Oracle选择使用nested loop的条件跟SQL Server有点差别,内存管理机制跟SQL Server不一样,因此查看执行计划,Oracle中nested loops运用非常多,而merge和hash方式相对较少,SQL Server中,merge跟hash方式则是非常普遍

优化原则

1.若有单行谓词,则他的表一定是驱动表(select * from employees e,departments d where e.department_id=d.department_id and e.department_id=100 and salary=10000; 上面的语句中e.department_id=d.department_id是连接谓词,e.department_id=100是非连接谓词(对连接列的限制),salary=10000是单行谓词(对非连接列的限制))

2.外连接时,一定是用显示的行数比较多的那个表作为驱动表。如:

select e.employee_id,e.department_id,d.manager_id,d.location_id from employees e right join departments d on e.department_id=d.department_id

则departments表显示的行数一定大于等于employees表,所以应该要以departments表作为驱动表,如果以employees表作为驱动表,则departments表中多显示的那几行就显示不出来了

4.一般情况下,Hash Join处理代价非常高,是数据库服务器内存和CPU的头号杀手之一,尤其是涉及到分区(数据量太大导致内存不够的情况,或者并发访问很高导致当前处理线程无法获得足够的内存,那么数据量不是特大的情况下也可能需要进行分区),为了尽快的完成所有的分区步骤,将使用大量异步的I/O操作,因此期间单一一个线程就可能导致多个磁盘驱动器出于忙碌状态,这很有可能阻塞其它线程的执行。

5. 要避免大数据的Hash Join,尽量将其转化为高效的Merge Join、Nested Loops。可能使用的手段有表结构设计、索引调整设计、SQL优化,以及业务设计优化。例如冗余字段的运用,将统计分析结果用service定期跑到静态表中,适当的冗余表,使用AOP或类似机制同步更新等。

6. 尽量减少join两个输入端的数据量。这一点比较常犯的毛病是,条件不符合SARG((Searchable Arguments),在子查询内部条件给的不充分(SQL过于复杂情况下SQL Server查询优化器经常犯傻,写在子查询外部的条件不会被用在子查询内部,影响子查询内部的效率或者是跟子查询再join时候的效率)。

参考 : 

https://www.sohu.com/a/215318964_99948066

https://www.cndba.cn/redhat/article/2479

原文地址:https://www.cnblogs.com/xiaohuizhenyoucai/p/11010524.html