1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

Allow statistics to be collected for foreign tables.

ANALYZE now accepts foreign tables and allows the table's FDW to control
how the sample rows are collected.  (But only manual ANALYZEs will touch
foreign tables, for the moment, since among other things it's not very
clear how to handle remote permissions checks in an auto-analyze.)

contrib/file_fdw is extended to support this.

Etsuro Fujita, reviewed by Shigeru Hanada, some further tweaking by me.
This commit is contained in:
Tom Lane
2012-04-06 15:02:35 -04:00
parent 8cb53654db
commit 263d9de66b
13 changed files with 486 additions and 101 deletions

View File

@ -10,8 +10,8 @@
<para>
All operations on a foreign table are handled through its foreign data
wrapper, which consists of a set of functions that the planner and
executor call. The foreign data wrapper is responsible for fetching
wrapper, which consists of a set of functions that the core server
calls. The foreign data wrapper is responsible for fetching
data from the remote data source and returning it to the
<productname>PostgreSQL</productname> executor. This chapter outlines how
to write a new foreign data wrapper.
@ -47,7 +47,8 @@
<para>
The handler function simply returns a struct of function pointers to
callback functions that will be called by the planner and executor.
callback functions that will be called by the planner, executor, and
various maintenance commands.
Most of the effort in writing an FDW is in implementing these callback
functions.
The handler function must be registered with
@ -276,6 +277,41 @@ EndForeignScan (ForeignScanState *node);
to remote servers should be cleaned up.
</para>
<para>
<programlisting>
AcquireSampleRowsFunc
AnalyzeForeignTable (Relation relation);
</programlisting>
This function is called when <xref linkend="sql-analyze"> is executed on
a foreign table. If the FDW supports collecting statistics for this
foreign table, it should return a pointer to a function that will collect
sample rows from the table. Otherwise, return <literal>NULL</>. If the
FDW does not support collecting statistics for any tables, the
<function>AnalyzeForeignTable</> pointer can be set to <literal>NULL</>.
</para>
<para>
If provided, the sample collection function must have the signature
<programlisting>
int
AcquireSampleRowsFunc (Relation relation, int elevel,
HeapTuple *rows, int targrows,
double *totalrows,
double *totaldeadrows,
BlockNumber *totalpages);
</programlisting>
A random sample of up to <parameter>targrows</> rows should be collected
from the table and stored into the caller-provided <parameter>rows</>
array. The actual number of rows collected must be returned. In
addition, store estimates of the total numbers of live rows, dead rows,
and pages in the table into the output parameters
<parameter>totalrows</>, <parameter>totaldeadrows</>, and
<parameter>totalpages</>. These numbers will be recorded in the table's
<structname>pg_class</> entry for future use.
</para>
<para>
The <structname>FdwRoutine</> struct type is declared in
<filename>src/include/foreign/fdwapi.h</>, which see for additional

View File

@ -332,6 +332,16 @@
plans that use the expression index.
</para>
</tip>
<tip>
<para>
The autovacuum daemon does not issue <command>ANALYZE</> commands for
foreign tables, since it has no means of determining how often that
might be useful. If your queries require statistics on foreign tables
for proper planning, it's a good idea to run manually-managed
<command>ANALYZE</> commands on those tables on a suitable schedule.
</para>
</tip>
</sect2>
<sect2 id="vacuum-for-visibility-map">

View File

@ -36,6 +36,9 @@ ALTER FOREIGN TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceab
DROP [ COLUMN ] [ IF EXISTS ] <replaceable class="PARAMETER">column</replaceable> [ RESTRICT | CASCADE ]
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> [ SET DATA ] TYPE <replaceable class="PARAMETER">type</replaceable>
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> { SET | DROP } NOT NULL
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> SET STATISTICS <replaceable class="PARAMETER">integer</replaceable>
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> SET ( <replaceable class="PARAMETER">attribute_option</replaceable> = <replaceable class="PARAMETER">value</replaceable> [, ... ] )
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> RESET ( <replaceable class="PARAMETER">attribute_option</replaceable> [, ... ] )
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> OPTIONS ( [ ADD | SET | DROP ] <replaceable class="PARAMETER">option</replaceable> ['<replaceable class="PARAMETER">value</replaceable>'] [, ... ])
OWNER TO <replaceable class="PARAMETER">new_owner</replaceable>
OPTIONS ( [ ADD | SET | DROP ] <replaceable class="PARAMETER">option</replaceable> ['<replaceable class="PARAMETER">value</replaceable>'] [, ... ])
@ -103,6 +106,31 @@ ALTER FOREIGN TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceab
</listitem>
</varlistentry>
<varlistentry>
<term><literal>SET STATISTICS</literal></term>
<listitem>
<para>
This form
sets the per-column statistics-gathering target for subsequent
<xref linkend="sql-analyze"> operations.
See the similar form of <xref linkend="sql-altertable">
for more details.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>SET ( <replaceable class="PARAMETER">attribute_option</replaceable> = <replaceable class="PARAMETER">value</replaceable> [, ... ] )</literal></term>
<term><literal>RESET ( <replaceable class="PARAMETER">attribute_option</replaceable> [, ... ] )</literal></term>
<listitem>
<para>
This form sets or resets per-attribute options.
See the similar form of <xref linkend="sql-altertable">
for more details.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>OWNER</literal></term>
<listitem>

View File

@ -63,7 +63,8 @@ ANALYZE [ VERBOSE ] [ <replaceable class="PARAMETER">table</replaceable> [ ( <re
<listitem>
<para>
The name (possibly schema-qualified) of a specific table to
analyze. Defaults to all tables in the current database.
analyze. If omitted, all regular tables (but not foreign tables)
in the current database are analyzed.
</para>
</listitem>
</varlistentry>
@ -92,6 +93,13 @@ ANALYZE [ VERBOSE ] [ <replaceable class="PARAMETER">table</replaceable> [ ( <re
<refsect1>
<title>Notes</title>
<para>
Foreign tables are analyzed only when explicitly selected. Not all
foreign data wrappers support <command>ANALYZE</>. If the table's
wrapper does not support <command>ANALYZE</>, the command prints a
warning and does nothing.
</para>
<para>
In the default <productname>PostgreSQL</productname> configuration,
the autovacuum daemon (see <xref linkend="autovacuum">)