Global Hints

到目前为止,hint已直接应用于SQL命令中引用的表。在SQL命令中引用视图时,也可以对视图中显示的表应用hint。hint本身不会在视图中显示,而是在引用视图的SQL命令中显示。

语法

指定要应用于视图中表的hint时,视图和表名称在提示参数列表中以点表示法指定。

hint(view.table)

参数

参数

说明

hint

表一表二中的任何提示。

view

包含table的视图的名称。

table

要对其应用hint的表。

示例

示例一

  1. 准备基础表格数据,请参考Access Method Hints示例。

  2. 创建视图tx,从pgbench_history、pgbench_branches和pgbench_accounts的三表联接创建,如Joining Relations Hints的最后一个示例中所示。

    CREATE VIEW tx AS SELECT h.mtime, h.delta, b.bid, a.aid FROM pgbench_history h, pgbench_branches b, pgbench_accounts a WHERE h.bid = b.bid AND h.aid = a.aid;
  3. 通过从此视图中选择生成的查询计划如下所示:

    EXPLAIN SELECT * FROM tx;

    返回结果如下:

                                           QUERY PLAN
    ----------------------------------------------------------------------------------------
     Hash Join  (cost=86814.29..123103.29 rows=500000 width=20)
       Hash Cond: (h.aid = a.aid)
       ->  Hash Join  (cost=21.45..15081.45 rows=500000 width=20)
             Hash Cond: (h.bid = b.bid)
             ->  Seq Scan on pgbench_history h  (cost=0.00..8185.00 rows=500000 width=20)
             ->  Hash  (cost=21.20..21.20 rows=20 width=4)
                   ->  Seq Scan on pgbench_branches b  (cost=0.00..21.20 rows=20 width=4)
       ->  Hash  (cost=53746.15..53746.15 rows=2014215 width=4)
             ->  Seq Scan on pgbench_accounts a  (cost=0.00..53746.15 rows=2014215 width=4)
    (9 rows)
  4. Joining Relations Hints末尾应用于此联接的相同hint可应用于该视图,如下所示:

    EXPLAIN SELECT /*+ USE_MERGE(tx.h tx.b) USE_HASH(tx.a) */ * FROM tx;

    返回结果如下:

                                                QUERY PLAN
    --------------------------------------------------------------------------------------------------
     Hash Join  (cost=152583.39..182562.49 rows=500000 width=20)
       Hash Cond: (h.aid = a.aid)
       ->  Merge Join  (cost=65790.55..74540.65 rows=500000 width=20)
             Merge Cond: (b.bid = h.bid)
             ->  Sort  (cost=21.63..21.68 rows=20 width=4)
                   Sort Key: b.bid
                   ->  Seq Scan on pgbench_branches b  (cost=0.00..21.20 rows=20 width=4)
             ->  Materialize  (cost=65768.92..68268.92 rows=500000 width=20)
                   ->  Sort  (cost=65768.92..67018.92 rows=500000 width=20)
                         Sort Key: h.bid
                         ->  Seq Scan on pgbench_history h  (cost=0.00..8185.00 rows=500000 width=20)
       ->  Hash  (cost=53746.15..53746.15 rows=2014215 width=4)
             ->  Seq Scan on pgbench_accounts a  (cost=0.00..53746.15 rows=2014215 width=4)
    (13 rows)

示例二

除了向存储视图中的表应用hint以外,还可以将hint应用于子查询中的表。

  1. 在以下示例中,应用程序emp表的此查询通过将emp表与别名b所标识的emp表的子查询进行联接,从而列出员工及其经理。

    CREATE TABLE emp (
        empno           NUMBER(4) NOT NULL CONSTRAINT emp_pk PRIMARY KEY,
        ename           VARCHAR2(10),
        job             VARCHAR2(9),
        mgr             NUMBER(4),
        hiredate        DATE,
        sal             NUMBER(7,2) CONSTRAINT emp_sal_ck CHECK (sal > 0),
        comm            NUMBER(7,2),
        deptno          NUMBER(2)
    );
    
    INSERT INTO emp VALUES (7369,'SMITH','CLERK',7902,'17-DEC-80',800,NULL,20);
    INSERT INTO emp VALUES (7499,'ALLEN','SALESMAN',7698,'20-FEB-81',1600,300,30);
    INSERT INTO emp VALUES (7521,'WARD','SALESMAN',7698,'22-FEB-81',1250,500,30);
    INSERT INTO emp VALUES (7566,'JONES','MANAGER',7839,'02-APR-81',2975,NULL,20);
    INSERT INTO emp VALUES (7654,'MARTIN','SALESMAN',7698,'28-SEP-81',1250,1400,30);
    INSERT INTO emp VALUES (7698,'BLAKE','MANAGER',7839,'01-MAY-81',2850,NULL,30);
    INSERT INTO emp VALUES (7782,'CLARK','MANAGER',7839,'09-JUN-81',2450,NULL,10);
    INSERT INTO emp VALUES (7788,'SCOTT','ANALYST',7566,'19-APR-87',3000,NULL,20);
    INSERT INTO emp VALUES (7839,'KING','PRESIDENT',NULL,'17-NOV-81',5000,NULL,10);
    INSERT INTO emp VALUES (7844,'TURNER','SALESMAN',7698,'08-SEP-81',1500,0,30);
    INSERT INTO emp VALUES (7876,'ADAMS','CLERK',7788,'23-MAY-87',1100,NULL,20);
    INSERT INTO emp VALUES (7900,'JAMES','CLERK',7698,'03-DEC-81',950,NULL,30);
    INSERT INTO emp VALUES (7902,'FORD','ANALYST',7566,'03-DEC-81',3000,NULL,20);
    INSERT INTO emp VALUES (7934,'MILLER','CLERK',7782,'23-JAN-82',1300,NULL,10);
    
    SELECT a.empno, a.ename, b.empno "mgr empno", b.ename "mgr ename" FROM emp a, (SELECT * FROM emp) b WHERE a.mgr = b.empno;

    返回结果如下:

     empno | ename  | mgr empno | mgr ename 
    -------+--------+-----------+-----------
      7369 | SMITH  |      7902 | FORD
      7499 | ALLEN  |      7698 | BLAKE
      7521 | WARD   |      7698 | BLAKE
      7566 | JONES  |      7839 | KING
      7654 | MARTIN |      7698 | BLAKE
      7698 | BLAKE  |      7839 | KING
      7782 | CLARK  |      7839 | KING
      7788 | SCOTT  |      7566 | JONES
      7844 | TURNER |      7698 | BLAKE
      7876 | ADAMS  |      7788 | SCOTT
      7900 | JAMES  |      7698 | BLAKE
      7902 | FORD   |      7566 | JONES
      7934 | MILLER |      7782 | CLARK
    (13 rows)
  2. 查询计划程序选择的计划如下所示:

    EXPLAIN SELECT a.empno, a.ename, b.empno "mgr empno", b.ename "mgr ename" FROM emp a, (SELECT * FROM emp) b WHERE a.mgr = b.empno;

    返回结果如下:

                                QUERY PLAN                             
    -------------------------------------------------------------------
     Hash Join  (cost=24.40..42.49 rows=640 width=52)
       Hash Cond: (a.mgr = emp.empno)
       ->  Seq Scan on emp a  (cost=0.00..16.40 rows=640 width=38)
       ->  Hash  (cost=16.40..16.40 rows=640 width=26)
             ->  Seq Scan on emp  (cost=0.00..16.40 rows=640 width=26)
    (5 rows)
  3. hint可应用于子查询中的emp表,以对索引emp_pk执行索引扫描,而不是表扫描。记下查询计划中的差异。

    EXPLAIN SELECT /*+ INDEX(b.emp emp_pk) */ a.empno, a.ename, b.empno "mgr empno", b.ename "mgr ename" FROM emp a, (SELECT * FROM emp) b WHERE a.mgr = b.empno;

    返回结果如下:

                                        QUERY PLAN                                    
    ----------------------------------------------------------------------------------
     Hash Join  (cost=29.85..47.94 rows=640 width=52)
       Hash Cond: (a.mgr = emp.empno)
       ->  Seq Scan on emp a  (cost=0.00..16.40 rows=640 width=38)
       ->  Hash  (cost=21.85..21.85 rows=640 width=26)
             ->  Index Scan using emp_pk on emp  (cost=0.15..21.85 rows=640 width=26)
    (5 rows)