similar behaviors, it is frequently useful to define cross-data-type
operators and allow these to work with indexes. To do this, the operator
classes for each of the types must be grouped into the same operator
family. The cross-type operators are members of the family, but are not
associated with any single class within the family.
</para>
<para>
This expanded version of the previous query shows the operator family
each operator class belongs to:
<programlisting>
SELECT am.amname AS index_method,
opc.opcname AS opclass_name,
opf.opfname AS opfamily_name,
opc.opcintype::regtype AS indexed_type,
opc.opcdefault AS is_default
FROM pg_am am, pg_opclass opc, pg_opfamily opf
WHERE opc.opcmethod = am.oid AND
opc.opcfamily = opf.oid
ORDER BY index_method, opclass_name;
</programlisting>
</para>
<para>
This query shows all defined operator families and all
the operators included in each family:
<programlisting>
SELECT am.amname AS index_method,
opf.opfname AS opfamily_name,
amop.amopopr::regoperator AS opfamily_operator
FROM pg_am am, pg_opfamily opf, pg_amop amop
WHERE opf.opfmethod = am.oid AND
amop.amopfamily = opf.oid
ORDER BY index_method, opfamily_name, opfamily_operator;
</programlisting>
</para>
<tip>
<para>
<xref linkend="app-psql"/> has
commands <command>\dAc</command>, <command>\dAf</command>,
and <command>\dAo</command>, which provide slightly more sophisticated
versions of these queries.
</para>
</tip>
</sect1>
<sect1 id="indexes-collations">
<title>Indexes and Collations</title>
<para>
An index can support only one collation per index column.
If multiple collations are of interest, multiple indexes may be needed.
</para>
<para>
Consider these statements:
<programlisting>
CREATE TABLE test1c (
id integer,
content varchar COLLATE "x"
);
CREATE INDEX test1c_content_index ON test1c (content);
</programlisting>
The index automatically uses the collation of the
underlying column. So a query of the form
<programlisting>
SELECT * FROM test1c WHERE content > <replaceable>constant</replaceable>;
</programlisting>
could use the index, because the comparison will by default use the
collation of the column. However, this index cannot accelerate queries
that involve some other collation. So if queries of the form, say,
<programlisting>
SELECT * FROM test1c WHERE content > <replaceable>constant</replaceable> COLLATE "y";
</programlisting>
are also of interest, an additional index could be created that supports
the <literal>"y"</literal> collation, like this:
<programlisting>
CREATE INDEX test1c_content_y_index ON test1c (content COLLATE "y");
</programlisting>
</para>
</sect1>
<sect1 id="indexes-examine">
<title>Examining Index Usage</title>
<indexterm zone="indexes-examine">
<primary>index</primary>
<secondary>examining usage</secondary>
</indexterm>
<para>
Although indexes in <productname>PostgreSQL</productname> do not need
maintenance or tuning, it is still important to check
which indexes are actually used by the real-life query workload.
Examining index usage for an individual query is done with the
<xref linkend="sql-explain"/>
command; its application for this purpose is
illustrated in <xref linkend="using-explain"/>.
It is also possible to gather overall statistics about index usage
in a running server, as described in <xref linkend="monitoring-stats"/>.
</para>
<para>
It is difficult to formulate a general procedure for determining
which indexes to create. There are a number of typical cases that
have been shown in the examples throughout the previous sections.
A good deal of experimentation is often necessary.
The rest of this section gives some