index scan for sorting many rows,
because of the nonsequential disk access required by the index scan.)
</para>
<para>
One way to look at variant plans is to force the planner to disregard
whatever strategy it thought was the cheapest, using the enable/disable
flags described in <xref linkend="runtime-config-query-enable"/>.
(This is a crude tool, but useful. See
also <xref linkend="explicit-joins"/>.)
For example, if we're unconvinced that merge join is the best join
type for the previous example, we could try
<screen>
SET enable_mergejoin = off;
EXPLAIN SELECT *
FROM tenk1 t1, onek t2
WHERE t1.unique1 < 100 AND t1.unique2 = t2.unique2;
QUERY PLAN
-------------------------------------------------------------------&zwsp;-----------------------
Hash Join (cost=226.23..344.08 rows=10 width=488)
Hash Cond: (t2.unique2 = t1.unique2)
-> Seq Scan on onek t2 (cost=0.00..114.00 rows=1000 width=244)
-> Hash (cost=224.98..224.98 rows=100 width=244)
-> Bitmap Heap Scan on tenk1 t1 (cost=5.06..224.98 rows=100 width=244)
Recheck Cond: (unique1 < 100)
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=100 width=0)
Index Cond: (unique1 < 100)
</screen>
which shows that the planner thinks that hash join would be nearly 50%
more expensive than merge join for this case.
Of course, the next question is whether it's right about that.
We can investigate that using <command>EXPLAIN ANALYZE</command>, as
discussed <link linkend="using-explain-analyze">below</link>.
</para>
<para>
When using the enable/disable flags to disable plan node types, many of
the flags only discourage the use of the corresponding plan node and don't
outright disallow the planner's ability to use the plan node type. This
is by design so that the planner still maintains the ability to form a
plan for a given query. When the resulting plan contains a disabled node,
the <command>EXPLAIN</command> output will indicate this fact.
<screen>
SET enable_seqscan = off;
EXPLAIN SELECT * FROM unit;
QUERY PLAN
---------------------------------------------------------
Seq Scan on unit (cost=0.00..21.30 rows=1130 width=44)
Disabled: true
</screen>
</para>
<para>
Because the <literal>unit</literal> table has no indexes, there is no
other means to read the table data, so the sequential scan is the only
option available to the query planner.
</para>
<para>
<indexterm>
<primary>subplan</primary>
</indexterm>
Some query plans involve <firstterm>subplans</firstterm>, which arise
from sub-<literal>SELECT</literal>s in the original query. Such
queries can sometimes be transformed into ordinary join plans, but
when they cannot be, we get plans like:
<screen>
EXPLAIN VERBOSE SELECT unique1
FROM tenk1 t
WHERE t.ten < ALL (SELECT o.ten FROM onek o WHERE o.four = t.four);
QUERY PLAN
-------------------------------------------------------------------&zwsp;------
Seq Scan on public.tenk1 t (cost=0.00..586095.00 rows=5000 width=4)
Output: t.unique1
Filter: (ALL (t.ten < (SubPlan 1).col1))
SubPlan 1
-> Seq Scan on public.onek o (cost=0.00..116.50 rows=250 width=4)
Output: o.ten
Filter: (o.four = t.four)
</screen>
This rather artificial example serves to illustrate a couple of
points: values from the outer plan level can be passed down into a
subplan (here, <literal>t.four</literal> is passed down) and the
results of the sub-select are available to the outer plan. Those
result values are shown by <command>EXPLAIN</command> with notations
like
<literal>(<replaceable>subplan_name</replaceable>).col<replaceable>N</replaceable></literal>,
which refers to the <replaceable>N</replaceable>'th