执行计划
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表进行顺序扫描遍历。

浙公网安备 33010602011771号