执行计划

http://blog.youkuaiyun.com/hantiannan/article/details/4517192

http://www.cnblogs.com/gaojian/archive/2012/11/08/2759874.html

http://m.oschina.net/blog/135872

http://wgzhao.com/2012/08/21/explaining-the-postgresql-query-optimizer/

http://blog.youkuaiyun.com/java3344520/article/details/5515497

执行计划查看:

从上到下,跟python代码类似,根据缩进查看。

操作关键字:

执行计划运算类型操作说明是否有启动时间
Seq Scan扫描表无启动时间
Index Scan索引扫描无启动时间
Bitmap Index Scan索引扫描有启动时间
Bitmap Heap Scan索引扫描有启动时间
Subquery Scan子查询无启动时间
Tid Scanctid = …条件无启动时间
Function Scan函数扫描无启动时间
Nested Loop循环结合无启动时间
Merge Join合并结合有启动时间
Hash Join哈希结合有启动时间
Sort排序,ORDER BY操作有启动时间
Hash哈希运算有启动时间
Result函数扫描,和具体的表无关无启动时间
UniqueDISTINCT,UNION操作有启动时间
LimitLIMIT,OFFSET操作有启动时间
Aggregatecount, sum,avg, stddev聚集函数有启动时间
GroupGROUP BY分组操作有启动时间
AppendUNION操作无启动时间
Materialize子查询有启动时间
SetOpINTERCECT,EXCEPT有启动时

几种表之间的连接方式:

Nested Loop 循环结合 

如果inner内表较小:
for(i=0;i < length(outer); i++)
  for(j=0; j < length(inner); j++)
     if (outer[i] ==  inner[j])
        output(outer[i],inner[j])

Merge Join 合并结合 

sort(outer);
sort(inner);
i=0;
j=0;
save_j=0;
while ( i < length(outer)) {
  if (outer[i] == inner[j])
     output[outer[i],inner[j])
  if (outer[i] >= inner[j] && j < length(inner)){
     j++;
     if (outer[i] < inner[j])
       save_j = j;
  else
     i++;
     j = save_j;
  }
}


Hash Join 哈希结合 

for (j = 0; j < length(inner); j++) {
    hash_key = hash(inner[j]);
    append(hash_store(hash_key),inner[j]);
}
for (i = 0; i < length(outer); i++) {
    hash_key = hash(outer[i]);
    for (j = 0; j < length(hash_store(hash_key]); j++)
        if (outer[i] == hash_store[hash_key][j])
            output(outer[i],inner[j]);
}

Nested Loop

将所有from部分涉及到的表都进行一次for循环。


举例说明:

demo1:
postgres=# EXPLAIN SELECT relname, nspname FROM pg_class JOIN
postgres-# pg_namespace ON (pg_class.relnamespace=pg_namespace.oid);
                               QUERY PLAN                                
-------------------------------------------------------------------------
 Hash Join  (cost=1.14..16.07 rows=292 width=128)#第1行
   Hash Cond: (pg_class.relnamespace = pg_namespace.oid)#第2行
   ->  Seq Scan on pg_class  (cost=0.00..10.92 rows=292 width=68)#第3行
   ->  Hash  (cost=1.06..1.06 rows=6 width=68)#第4行
         ->  Seq Scan on pg_namespace  (cost=0.00..1.06 rows=6 width=68)#第5行
(5 rows)
第1行:是操作关键字hash join ,其下的缩进(距离小于第1行的行)都是对这个hash join解释。

第2行:hash join的条件。

第3行:顺序扫描遍历pg_class表(inner内表),在系统内存中形成一个hash内存块。

第4行:由于第3,4行缩进一样,所以是同级别的。用第3行形成的内存块进行hash运算,其对象是第5行描述的pg_namespace表。

第5行:对pg_namespace表进行顺序扫描遍历。


demo2:

create table tb1_join_1  (id int primary key, info text);
create table tb1_join_2  (id int primary key, info text);
create table tb1_join_3  (id int primary key, info text);
create table tb1_join_4  (id int primary key, info text);
create table tb1_join_5  (id int primary key, info text);
create table tb1_join_6  (id int primary key, info text);
create table tb1_join_7  (id int primary key, info text);
create table tb1_join_8  (id int primary key, info text);
create table tb1_join_9  (id int primary key, info text);

insert into tb1_join_1 select generate_series(1,10), '测试数据';
insert into tb1_join_2 select generate_series(1,100), '测试数据';
insert into tb1_join_3 select generate_series(1,1000), '测试数据';
insert into tb1_join_4 select generate_series(1,10000), '测试数据';
insert into tb1_join_5 select generate_series(1,100000), '测试数据';
insert into tb1_join_6 select generate_series(1,1000000), '测试数据';
insert into tb1_join_7 select generate_series(1,2000000), '测试数据';
insert into tb1_join_8 select generate_series(1,4000000), '测试数据';
insert into tb1_join_9 select generate_series(1,8000000), '测试数据';

postgres=# explain select t1.info, t5.info
from 
tb1_join_1 t1,
tb1_join_2 t2,
tb1_join_3 t3,
tb1_join_4 t4,
tb1_join_5 t5,
tb1_join_6 t6,
tb1_join_7 t7,
tb1_join_8 t8,
tb1_join_9 t9
where 
t1.id=t2.id and
t2.id=t3.id and
t3.id=t4.id and
t4.id=t5.id and
t5.id=t6.id and
t6.id=t7.id and
t7.id=t8.id and
t8.id=t9.id and
t9.id=10000;
                                                              QUERY PLAN                                                              
--------------------------------------------------------------------------------------------------------------------------------------
 Nested Loop  (cost=2.72..69.19 rows=1 width=45)
   ->  Nested Loop  (cost=2.29..60.73 rows=1 width=49)
         ->  Nested Loop  (cost=1.86..52.27 rows=1 width=49)
               ->  Nested Loop  (cost=1.43..43.82 rows=1 width=49)
                     ->  Nested Loop  (cost=1.00..35.37 rows=1 width=49)
                           ->  Nested Loop  (cost=0.71..27.05 rows=1 width=36)
                                 ->  Nested Loop  (cost=0.43..18.73 rows=1 width=36)
                                       ->  Nested Loop  (cost=0.15..10.43 rows=1 width=36)
                                             ->  Index Scan using tb1_join_1_pkey on tb1_join_1 t1  (cost=0.15..8.17 rows=1 width=36)
                                                   Index Cond: (id = 10000)
                                             ->  Seq Scan on tb1_join_2 t2  (cost=0.00..2.25 rows=1 width=4)
                                                   Filter: (id = 10000)
                                       ->  Index Only Scan using tb1_join_3_pkey on tb1_join_3 t3  (cost=0.28..8.29 rows=1 width=4)
                                             Index Cond: (id = 10000)
                                 ->  Index Only Scan using tb1_join_4_pkey on tb1_join_4 t4  (cost=0.29..8.30 rows=1 width=4)
                                       Index Cond: (id = 10000)
                           ->  Index Scan using tb1_join_5_pkey on tb1_join_5 t5  (cost=0.29..8.31 rows=1 width=17)
                                 Index Cond: (id = 10000)
                     ->  Index Only Scan using tb1_join_6_pkey on tb1_join_6 t6  (cost=0.42..8.44 rows=1 width=4)
                           Index Cond: (id = 10000)
               ->  Index Only Scan using tb1_join_7_pkey on tb1_join_7 t7  (cost=0.43..8.45 rows=1 width=4)
                     Index Cond: (id = 10000)
         ->  Index Only Scan using tb1_join_8_pkey on tb1_join_8 t8  (cost=0.43..8.45 rows=1 width=4)
               Index Cond: (id = 10000)
   ->  Index Only Scan using tb1_join_9_pkey on tb1_join_9 t9  (cost=0.43..8.45 rows=1 width=4)
         Index Cond: (id = 10000)
(26 rows)

Time: 15.473 ms

postgres=# explain select t1.info, t5.info
postgres-# from 
postgres-# tb1_join_1 t1
postgres-# join tb1_join_2 t2 on (t1.id=t2.id)
postgres-# join tb1_join_3 t3 on (t2.id=t3.id)
postgres-# join tb1_join_4 t4 on (t3.id=t4.id)
postgres-# join tb1_join_5 t5 on (t4.id=t5.id)
postgres-# join tb1_join_6 t6 on (t5.id=t6.id)
postgres-# join tb1_join_7 t7 on (t6.id=t7.id)
postgres-# join tb1_join_8 t8 on (t7.id=t8.id)
postgres-# join tb1_join_9 t9 on (t8.id=t9.id)
postgres-# where t9.id=10000;
                                                              QUERY PLAN                                                              
--------------------------------------------------------------------------------------------------------------------------------------
 Nested Loop  (cost=2.72..69.19 rows=1 width=45)
   ->  Nested Loop  (cost=2.29..60.73 rows=1 width=49)
         ->  Nested Loop  (cost=1.86..52.27 rows=1 width=49)
               ->  Nested Loop  (cost=1.43..43.82 rows=1 width=49)
                     ->  Nested Loop  (cost=1.00..35.37 rows=1 width=49)
                           ->  Nested Loop  (cost=0.71..27.05 rows=1 width=36)
                                 ->  Nested Loop  (cost=0.43..18.73 rows=1 width=36)
                                       ->  Nested Loop  (cost=0.15..10.43 rows=1 width=36)
                                             ->  Index Scan using tb1_join_1_pkey on tb1_join_1 t1  (cost=0.15..8.17 rows=1 width=36)
                                                   Index Cond: (id = 10000)
                                             ->  Seq Scan on tb1_join_2 t2  (cost=0.00..2.25 rows=1 width=4)
                                                   Filter: (id = 10000)
                                       ->  Index Only Scan using tb1_join_3_pkey on tb1_join_3 t3  (cost=0.28..8.29 rows=1 width=4)
                                             Index Cond: (id = 10000)
                                 ->  Index Only Scan using tb1_join_4_pkey on tb1_join_4 t4  (cost=0.29..8.30 rows=1 width=4)
                                       Index Cond: (id = 10000)
                           ->  Index Scan using tb1_join_5_pkey on tb1_join_5 t5  (cost=0.29..8.31 rows=1 width=17)
                                 Index Cond: (id = 10000)
                     ->  Index Only Scan using tb1_join_6_pkey on tb1_join_6 t6  (cost=0.42..8.44 rows=1 width=4)
                           Index Cond: (id = 10000)
               ->  Index Only Scan using tb1_join_7_pkey on tb1_join_7 t7  (cost=0.43..8.45 rows=1 width=4)
                     Index Cond: (id = 10000)
         ->  Index Only Scan using tb1_join_8_pkey on tb1_join_8 t8  (cost=0.43..8.45 rows=1 width=4)
               Index Cond: (id = 10000)
   ->  Index Only Scan using tb1_join_9_pkey on tb1_join_9 t9  (cost=0.43..8.45 rows=1 width=4)
         Index Cond: (id = 10000)
(26 rows)

Time: 6.298 ms





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值