PostgreSQL hint用法(兼容oracle)

Hint是Oracle数据库中很有特色的一个功能,pg和oracle的优化器一样也是CBO(基于成本的)。但是在pg中是没有hint的,但是我们可以去通过设置成本因子,设置优化器开关等方式来"建议"数据库按照我们的想法去生成执行计划,但是并不能强制,例如:

bill=# explain select * from t1;
                      QUERY PLAN                       
-------------------------------------------------------
 Seq Scan on t1  (cost=0.00..22.70 rows=1270 width=36)
(1 row)

对于上面这个简单的全部扫描查询,即使我们关闭全表扫描开关也没用:

bill=# set enable_seqscan TO off;
SET
bill=# explain select * from t1; 
                                QUERY PLAN                                
--------------------------------------------------------------------------
 Seq Scan on t1  (cost=10000000000.00..10000000022.70 rows=1270 width=36)
(1 row)

那么我们能否在pg中使用像oracle的hint的方法呢?答案是可以的,pg提供了一个pg_hint_plan的插件,可以完成类似的功能。

测试:
下载地址:http://iij.dl.sourceforge.jp/pghintplan/

安装:
pg11@oracle-> tar -zxvf pg_hint_plan11-1.3.4.tar.gz
pg11@oracle-> cd pg_hint_plan11-1.3.4
pg11@oracle-> gmake clean
pg11@oracle-> gmake
pg11@oracle-> gmake install
pg11@oracle-> vi $PGDATA/postgresql.conf
–添加以下内容
shared_preload_libraries = ‘pg_hint_plan’
pg_hint_plan.enable_hint = on
pg_hint_plan.debug_print = on
pg_hint_plan.message_level = log

pg11@oracle-> pg_ctl restart -m fast

使用:

pg11@oracle-> psql bill bill
psql (11.1)
Type "help" for help.

bill=# create extension pg_hint_plan ;
CREATE EXTENSION

用法举例:

bill=# create table a(id int primary key, info text, crt_time timestamp);  
CREATE TABLE
bill=# create table b(id int primary key, info text, crt_time timestamp);  
CREATE TABLE
bill=# insert into a select generate_series(1,100000), 'a_'||md5(random()::text), clock_timestamp();  
INSERT 0 100000
bill=# insert into b select generate_series(1,100000), 'b_'||md5(random()::text), clock_timestamp(); 
INSERT 0 100000
bill=# analyze a;  
ANALYZE
bill=# analyze b;
ANALYZE
bill=# explain select a.*,b.* from a,b where a.id=b.id and a.id<10; 
                              QUERY PLAN                               
-----------------------------------------------------------------------
 Nested Loop  (cost=0.58..29.24 rows=9 width=94)
   ->  Index Scan using a_pkey on a  (cost=0.29..3.05 rows=9 width=47)
         Index Cond: (id < 10)
   ->  Index Scan using b_pkey on b  (cost=0.29..2.91 rows=1 width=47)
         Index Cond: (id = a.id)
(5 rows)

使用pg_hint_plan来改变执行计划 :

bill=# /*+                                   
bill*#   HashJoin(a b)  
bill*#   SeqScan(b)  
bill*# */ explain select a.*,b.* from a,b where a.id=b.id and a.id<10;  
                                 QUERY PLAN                                  
-----------------------------------------------------------------------------
 Hash Join  (cost=3.16..2200.67 rows=9 width=94)
   Hash Cond: (b.id = a.id)
   ->  Seq Scan on b  (cost=0.00..1935.00 rows=100000 width=47)
   ->  Hash  (cost=3.05..3.05 rows=9 width=47)
         ->  Index Scan using a_pkey on a  (cost=0.29..3.05 rows=9 width=47)
               Index Cond: (id < 10)
(6 rows)

更多使用方法举例:

bill=# /*+ SeqScan(a) */ explain select * from a where id<10;  
                     QUERY PLAN                      
-----------------------------------------------------
 Seq Scan on a  (cost=0.00..2185.00 rows=9 width=47)
   Filter: (id < 10)
(2 rows)

bill=# /*+ BitmapScan(a) */ explain select * from a where id<10;
                             QUERY PLAN                              
---------------------------------------------------------------------
 Bitmap Heap Scan on a  (cost=1.66..13.21 rows=9 width=47)
   Recheck Cond: (id < 10)
   ->  Bitmap Index Scan on a_pkey  (cost=0.00..1.66 rows=9 width=0)
         Index Cond: (id < 10)
(4 rows)

目前pg_hint_plan支持的hint类型:
http://pghintplan.sourceforge.jp/hint_list.html

你可能感兴趣的:(PostgreSQL)