Global hints v15
In addition to applying hints directly to tables that are referenced in the SQL command, you can apply hints to tables that appear in a view when the view is referenced in the SQL command. The hint doesn't appear in the view but in the SQL command that references the view.
When specifying a hint that applies to a table in a view, give the view and table names in dot notation in the hint argument list.
Synopsis
<hint>(<view>.<table>)
Parameters
hint
Any of the hints in the table Access method hints, Joining relations hints.
view
The name of the view containing table
.
table
The table on which to apply the hint.
Example: Applying hints to a stored view
A view named tx
is created from the three-table join of pgbench_history
, pgbench_branches
, and pgbench_accounts
, shown in the last example of 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;
The query plan produced by selecting from this view is:
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)
The same hints that were applied to this join at the end of Joining relations hints can be applied to the view:
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)
Applying hints to tables in subqueries
In addition to applying hints to tables in stored views, you can apply hints to tables in subqueries. In this query on the sample application emp
table, employees and their managers are listed by joining the emp
table with a subquery of the emp
table identified by the alias b
:
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)
This code shows the plan chosen by the query planner:
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)
You can apply a hint to the emp
table in the subquery to perform an index scan on index emp_pk
instead of a table scan. Note the difference in the query plans.
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)