到目前为止,hint已直接应用于 SQL 命令中引用的表。在 SQL 命令中引用视图时,也可以对视图中显示的表应用hint。hint本身不会在视图中显示,而是在引用视图的 SQL 命令中显示。
指定要应用于视图中表的hint时,视图和表名称在提示参数列表中以点表示法指定。
概要
hint(view.table)
参数
参数 | 说明 |
hint | |
view | 包含table的视图的名称。 |
table | 要对其应用hint的表。 |
示例
名为 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 表的子查询,列出员工及其经理。
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=1.32..2.64 rows=13 width=22)
Hash Cond: (a.mgr = emp.empno)
-> Seq Scan on emp a (cost=0.00..1.14 rows=14 width=16)
-> Hash (cost=1.14..1.14 rows=14 width=11)
-> Seq Scan on emp (cost=0.00..1.14 rows=14 width=11)
(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
---------------------------------------------------------------------------
Merge Join (cost=4.17..13.11 rows=13 width=22)
Merge Cond: (a.mgr = emp.empno)
-> Sort (cost=1.41..1.44 rows=14 width=16)
Sort Key: a.mgr
-> Seq Scan on emp a (cost=0.00..1.14 rows=14 width=16)
-> Index Scan using emp_pk on emp (cost=0.14..12.35 rows=14 width=11)
(6 rows)
文档内容是否对您有帮助?