到目前为止,hint已直接应用于SQL命令中引用的表。在SQL命令中引用视图时,也可以对视图中显示的表应用hint。hint本身不会在视图中显示,而是在引用视图的SQL命令中显示。
语法
指定要应用于视图中表的hint时,视图和表名称在提示参数列表中以点表示法指定。
hint(view.table)
参数
参数 | 说明 |
hint | |
view | 包含table的视图的名称。 |
table | 要对其应用hint的表。 |
示例
示例一
准备基础表格数据,请参考Access Method Hints示例。
创建视图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;
通过从此视图中选择生成的查询计划如下所示:
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)
在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应用于子查询中的表。
在以下示例中,应用程序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)
查询计划程序选择的计划如下所示:
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)
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)
文档内容是否对您有帮助?