@@ -985,10 +985,54 @@ CREATE UNIQUE INDEX tests_target_one_null ON tests ((target IS NULL)) WHERE targ
985
985
know at least as much as the query planner knows, in particular you
986
986
know when an index might be profitable. Forming this knowledge
987
987
requires experience and understanding of how indexes in
988
- <productname>PostgreSQL</productname> work. In most cases, the advantage of a
989
- partial index over a regular index will be minimal.
988
+ <productname>PostgreSQL</productname> work. In most cases, the
989
+ advantage of a partial index over a regular index will be minimal.
990
+ There are cases where they are quite counterproductive, as in <xref
991
+ linkend="indexes-partial-ex4"/>.
990
992
</para>
991
993
994
+ <example id="indexes-partial-ex4">
995
+ <title>Do Not Use Partial Indexes as a Substitute for Partitioning</title>
996
+
997
+ <para>
998
+ You might be tempted to create a large set of non-overlapping partial
999
+ indexes, for example
1000
+
1001
+ <programlisting>
1002
+ CREATE INDEX mytable_cat_1 ON mytable (data) WHERE category = 1;
1003
+ CREATE INDEX mytable_cat_2 ON mytable (data) WHERE category = 2;
1004
+ CREATE INDEX mytable_cat_3 ON mytable (data) WHERE category = 3;
1005
+ ...
1006
+ CREATE INDEX mytable_cat_<replaceable>N</replaceable> ON mytable (data) WHERE category = <replaceable>N</replaceable>;
1007
+ </programlisting>
1008
+
1009
+ This is a bad idea! Almost certainly, you'll be better off with a
1010
+ single non-partial index, declared like
1011
+
1012
+ <programlisting>
1013
+ CREATE INDEX mytable_cat_data ON mytable (category, data);
1014
+ </programlisting>
1015
+
1016
+ (Put the category column first, for the reasons described in
1017
+ <xref linkend="indexes-multicolumn"/>.) While a search in this larger
1018
+ index might have to descend through a couple more tree levels than a
1019
+ search in a smaller index, that's almost certainly going to be cheaper
1020
+ than the planner effort needed to select the appropriate one of the
1021
+ partial indexes. The core of the problem is that the system does not
1022
+ understand the relationship among the partial indexes, and will
1023
+ laboriously test each one to see if it's applicable to the current
1024
+ query.
1025
+ </para>
1026
+
1027
+ <para>
1028
+ If your table is large enough that a single index really is a bad idea,
1029
+ you should look into using partitioning instead (see
1030
+ <xref linkend="ddl-partitioning"/>). With that mechanism, the system
1031
+ does understand that the tables and indexes are non-overlapping, so
1032
+ far better performance is possible.
1033
+ </para>
1034
+ </example>
1035
+
992
1036
<para>
993
1037
More information about partial indexes can be found in <xref
994
1038
linkend="ston89b"/>, <xref linkend="olson93"/>, and <xref
0 commit comments