执行计划
http://blog.csdn.net/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.csdn.net/java3344520/article/details/5515497
执行计划查看:
从上到下,跟python代码类似,根据缩进查看。
操作关键字:
执行计划运算类型 | 操作说明 | 是否有启动时间 |
---|---|---|
Seq Scan | 扫描表 | 无启动时间 |
Index Scan | 索引扫描 | 无启动时间 |
Bitmap Index Scan | 索引扫描 | 有启动时间 |
Bitmap Heap Scan | 索引扫描 | 有启动时间 |
Subquery Scan | 子查询 | 无启动时间 |
Tid Scan | ctid = …条件 | 无启动时间 |
Function Scan | 函数扫描 | 无启动时间 |
Nested Loop | 循环结合 | 无启动时间 |
Merge Join | 合并结合 | 有启动时间 |
Hash Join | 哈希结合 | 有启动时间 |
Sort | 排序,ORDER BY操作 | 有启动时间 |
Hash | 哈希运算 | 有启动时间 |
Result | 函数扫描,和具体的表无关 | 无启动时间 |
Unique | DISTINCT,UNION操作 | 有启动时间 |
Limit | LIMIT,OFFSET操作 | 有启动时间 |
Aggregate | count, sum,avg, stddev聚集函数 | 有启动时间 |
Group | GROUP BY分组操作 | 有启动时间 |
Append | UNION操作 | 无启动时间 |
Materialize | 子查询 | 有启动时间 |
SetOp | INTERCECT,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]); }
举例说明:
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表进行顺序扫描遍历。