设为首页 加入收藏

TOP

PostgreSQL学习手册(性能提升技巧)(二)
2014-11-24 00:56:39 来源: 作者: 【 】 浏览:25
Tags:PostgreSQL 学习 手册 性能 提升 技巧
e1 on tenk1 (cost=0.00..10.01 rows=1 width=244)
Index Cond: (unique1 < 3)
Filter: (stringu1 = 'xxx'::name)
新增的过滤条件stringu1 = 'xxx'只是减少了预计输出的行数,但是并没有减少实际开销,因为我们仍然需要访问相同数量的数据行。而该条件并没有作为一个索引条件,而是被当成对索引结果的过滤条件来看待。
如果WHERE条件里有多个字段存在索引,那么规划器可能会使用索引的AND或OR的组合,如:
EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000;
QUERY PLAN
-------------------------------------------------------------------------------------
Bitmap Heap Scan on tenk1 (cost=11.27..49.11 rows=11 width=244)
Recheck Cond: ((unique1 < 100) AND (unique2 > 9000))
-> BitmapAnd (cost=11.27..11.27 rows=11 width=0)
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..2.37 rows=106 width=0)
Index Cond: (unique1 < 100) www.2cto.com
-> Bitmap Index Scan on tenk1_unique2 (cost=0.00..8.65 rows=1042 width=0)
Index Cond: (unique2 > 9000)
这样的结果将会导致访问两个索引,与只使用一个索引,而把另外一个条件只当作过滤器相比,这个方法未必是更优。
现在让我们来看一下基于索引字段进行表连接的查询规划,如:
EXPLAIN SELECT * FROM tenk1 t1, tenk2 t2 WHERE t1.unique1 < 100 AND t1.unique2 = t2.unique2;
QUERY PLAN
--------------------------------------------------------------------------------------
Nested Loop (cost=2.37..553.11 rows=106 width=488)
-> Bitmap Heap Scan on tenk1 t1 (cost=2.37..232.35 rows=106 width=244)
Recheck Cond: (unique1 < 100)
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..2.37 rows=106 width=0)
Index Cond: (unique1 < 100)
-> Index Scan using tenk2_unique2 on tenk2 t2 (cost=0.00..3.01 rows=1 width=244)
Index Cond: ("outer".unique2 = t2.unique2)
从查询规划中可以看出(Nested Loop)该查询语句使用了嵌套循环。外层的扫描是一个位图索引,因此其开销与行计数和之前查询的开销是相同的,这是因为条件unique1 < 100发挥了作用。 这个时候t1.unique2 = t2.unique2条件子句还没有产生什么作用,因此它不会影响外层扫描的行计数。然而对于内层扫描而言,当前外层扫描的数据行将被插入到内层索引扫描中,并生成类似的条件t2.unique2 = constant。所以,内层扫描将得到和EXPLAIN SELECT * FROM tenk2 WHERE unique2 = 42一样的计划和开销。最后,以外层扫描的开销为基础设置循环节点的开销,再加上每个外层行的一个迭代(这里是 106 * 3.01),以及连接处理需要的一点点CPU时间。
如果不想使用嵌套循环的方式来规划上面的查询,那么我们可以通过执行以下系统设置,以关闭嵌套循环,如:
SET enable_nestloop = off;
EXPLAIN SELECT * FROM tenk1 t1, tenk2 t2 WHERE t1.unique1 < 100 AND t1.unique2 = t2.unique2;
QUERY PLAN
------------------------------------------------------------------------------------------
Hash Join (cost=232.61..741.67 rows=106 width=488)
Hash Cond: ("outer".unique2 = "inner".unique2)
-> Seq Scan on tenk2 t2 (cost=0.00..458.00 rows=10000 width=244)
-> Hash (cost=232.35..232.35 rows=106 width=244) www.2cto.com
-> Bitmap Heap Scan on tenk1 t1 (cost=2.37..232.35 rows=106 width=244)
Recheck Cond: (unique1 < 100)
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..2.37 rows=106 width=0)
Index Cond: (unique1 < 100)
这个规划仍然试图用同样的索引扫描从tenk1里面取出符合要求的100行,并把它们存储在内存中的散列(哈希)表里,然后对tenk2做一次全表顺序扫描,并为每一条tenk2中的记录查询散列(哈希)表,寻找可能匹配t1.unique2 = t2.unique2的行。读取tenk1和建立散列表是此散列联接的全部启动开销,因为我们在开始读取tenk2之前不可能获得任何输出行。
此外,我们还可以用EXPLAIN ANALYZE命令检查规划器预估值的准确性。这个命令将先执行该查询,然后显示每个规划节点内实际运行时间,以及单纯EXPLAIN命令显示的预计开销,如:
EXPLAIN ANALYZE SELECT * FROM tenk1 t1, tenk2 t2 WHERE t1.unique1 < 100 AND t1.unique2 = t2.unique2;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------
Nested Loop (cost=2.37..553.11 rows=106 width=488) (actual time=1.392..12.700 rows=100 loops=1)
-> Bitmap Heap Scan on tenk1 t1 (cost=2.37..232.35 rows=106 width=244) (actual time=0.878.
首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇PostgreSQL学习手册(常用数据类型) 下一篇PostgreSQL学习手册(表的继承和分..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: