作者:瀚高PG实验室 (Highgo PG Lab)- z
#Nestloop Join
嵌套循环(Nestloop Join)是在两个表连接时一种连接方式。在嵌套循环中,内表被外表驱动,外表返回的每一行都要在内表中检索找到与它匹配的行,因此整个查询返回的结果集不能太大,要把返回子集较小的表作为外表,且内表的连接字段上要有索引。
执行过程:确定一个驱动表(outer table),另一个表为inner table,驱动表中每一行与inner table中的相应记录关联。
示例如下:
highgo=# explain select * from people,dept where dept.deptno=people.id;
QUERY PLAN
---------------------------------------------------------------------------
Nested Loop (cost=0.44..5719.30 rows=680 width=100)
-> Seq Scan on dept (cost=0.00..16.80 rows=680 width=92)
-> Index Scan using inx_id on people (cost=0.44..8.38 rows=1 width=8)
Index Cond: (id = dept.deptno)
(4 行记录)
#Hash Join
优化器使用两个比较的表,并利用连接键在内存中建立散列表,然后扫描较大的表并探测散列表,找出与散列表匹配的行。
这种方式适用于较小的表可以完全放于内存中的情况,这样总成本就是访问两个表的成本之和。但如果表很大,不能完全放入内存,优化器会将它分割成若干不听的分区,把不能放入内存的部分写入磁盘的临时段,此时要有较大的临时段以便提高I/O的性能。
示例如下:
highgo=# explain select * from test,dept where dept.deptno=test.deptno;
QUERY PLAN
--------------------------------------------------------------------
Hash Join (cost=25.30..1870.22 rows=57344 width=127)
Hash Cond: (test.deptno = dept.deptno)
-> Seq Scan on test (cost=0.00..1056.44 rows=57344 width=35)
-> Hash (cost=16.80..16.80 rows=680 width=92)
-> Seq Scan on dept (cost=0.00..16.80 rows=680 width=92)
(5 行记录)
因为dept表小于test表,所以Hash Join先在较小的表dept上建立散列表,然后扫描较大的表test,并探测散列表,找出与之相匹配的行。