tables.
</para>
<para>
To force the planner to follow the join order laid out by explicit
<literal>JOIN</literal>s,
set the <xref linkend="guc-join-collapse-limit"/> run-time parameter to 1.
(Other possible values are discussed below.)
</para>
<para>
You do not need to constrain the join order completely in order to
cut search time, because it's OK to use <literal>JOIN</literal> operators
within items of a plain <literal>FROM</literal> list. For example, consider:
<programlisting>
SELECT * FROM a CROSS JOIN b, c, d, e WHERE ...;
</programlisting>
With <varname>join_collapse_limit</varname> = 1, this
forces the planner to join A to B before joining them to other tables,
but doesn't constrain its choices otherwise. In this example, the
number of possible join orders is reduced by a factor of 5.
</para>
<para>
Constraining the planner's search in this way is a useful technique
both for reducing planning time and for directing the planner to a
good query plan. If the planner chooses a bad join order by default,
you can force it to choose a better order via <literal>JOIN</literal> syntax
— assuming that you know of a better order, that is. Experimentation
is recommended.
</para>
<para>
A closely related issue that affects planning time is collapsing of
subqueries into their parent query. For example, consider:
<programlisting>
SELECT *
FROM x, y,
(SELECT * FROM a, b, c WHERE something) AS ss
WHERE somethingelse;
</programlisting>
This situation might arise from use of a view that contains a join;
the view's <literal>SELECT</literal> rule will be inserted in place of the view
reference, yielding a query much like the above. Normally, the planner
will try to collapse the subquery into the parent, yielding:
<programlisting>
SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
</programlisting>
This usually results in a better plan than planning the subquery
separately. (For example, the outer <literal>WHERE</literal> conditions might be such that
joining X to A first eliminates many rows of A, thus avoiding the need to
form the full logical output of the subquery.) But at the same time,
we have increased the planning time; here, we have a five-way join
problem replacing two separate three-way join problems. Because of the
exponential growth of the number of possibilities, this makes a big
difference. The planner tries to avoid getting stuck in huge join search
problems by not collapsing a subquery if more than <varname>from_collapse_limit</varname>
<literal>FROM</literal> items would result in the parent
query. You can trade off planning time against quality of plan by
adjusting this run-time parameter up or down.
</para>
<para>
<xref linkend="guc-from-collapse-limit"/> and <xref
linkend="guc-join-collapse-limit"/>
are similarly named because they do almost the same thing: one controls
when the planner will <quote>flatten out</quote> subqueries, and the
other controls when it will flatten out explicit joins. Typically
you would either set <varname>join_collapse_limit</varname> equal to
<varname>from_collapse_limit</varname> (so that explicit joins and subqueries
act similarly) or set <varname>join_collapse_limit</varname> to 1 (if you want
to control join order with explicit joins). But you might set them
differently if you are trying to fine-tune the trade-off between planning
time and run time.
</para>
</sect1>
<sect1 id="populate">
<title>Populating a Database</title>
<para>
One might need to insert a large amount of data when first populating
a database. This section contains some suggestions on how to make
this process as efficient as possible.
</para>
<sect2 id="disable-autocommit">
<title>Disable Autocommit</title>
<indexterm>
<primary>autocommit</primary>
<secondary>bulk-loading data</secondary>