Home Explore Blog CI



postgresql

14th chunk of `doc/src/sgml/rules.sgml`
11aa71f25ba9156fdc9f0f6d28516de7f84ca3a92dbbd7fb0000000100000fab
 using <literal>file_fdw</literal> is below, with timings,
    but since this is using cache on the local system the performance
    difference compared to access to a remote system would usually be greater
    than shown here.  Notice we are also exploiting the ability to put an
    index on the materialized view, whereas <literal>file_fdw</literal> does
    not support indexes; this advantage might not apply for other sorts of
    foreign data access.
</para>

<para>
    Setup:

<programlisting>
CREATE EXTENSION file_fdw;
CREATE SERVER local_file FOREIGN DATA WRAPPER file_fdw;
CREATE FOREIGN TABLE words (word text NOT NULL)
  SERVER local_file
  OPTIONS (filename '/usr/share/dict/words');
CREATE MATERIALIZED VIEW wrd AS SELECT * FROM words;
CREATE UNIQUE INDEX wrd_word ON wrd (word);
CREATE EXTENSION pg_trgm;
CREATE INDEX wrd_trgm ON wrd USING gist (word gist_trgm_ops);
VACUUM ANALYZE wrd;
</programlisting>

    Now let's spell-check a word.  Using <literal>file_fdw</literal> directly:

<programlisting>
SELECT count(*) FROM words WHERE word = 'caterpiler';

 count
-------
     0
(1 row)
</programlisting>

    With <command>EXPLAIN ANALYZE</command>, we see:

<programlisting>
 Aggregate  (cost=21763.99..21764.00 rows=1 width=0) (actual time=188.180..188.181 rows=1.00 loops=1)
   -&gt;  Foreign Scan on words  (cost=0.00..21761.41 rows=1032 width=0) (actual time=188.177..188.177 rows=0.00 loops=1)
         Filter: (word = 'caterpiler'::text)
         Rows Removed by Filter: 479829
         Foreign File: /usr/share/dict/words
         Foreign File Size: 4953699
 Planning time: 0.118 ms
 Execution time: 188.273 ms
</programlisting>

    If the materialized view is used instead, the query is much faster:

<programlisting>
 Aggregate  (cost=4.44..4.45 rows=1 width=0) (actual time=0.042..0.042 rows=1.00 loops=1)
   -&gt;  Index Only Scan using wrd_word on wrd  (cost=0.42..4.44 rows=1 width=0) (actual time=0.039..0.039 rows=0.00 loops=1)
         Index Cond: (word = 'caterpiler'::text)
         Heap Fetches: 0
         Index Searches: 1
 Planning time: 0.164 ms
 Execution time: 0.117 ms
</programlisting>

    Either way, the word is spelled wrong, so let's look for what we might
    have wanted.  Again using <literal>file_fdw</literal> and
    <literal>pg_trgm</literal>:

<programlisting>
SELECT word FROM words ORDER BY word &lt;-&gt; 'caterpiler' LIMIT 10;

     word
---------------
 cater
 caterpillar
 Caterpillar
 caterpillars
 caterpillar's
 Caterpillar's
 caterer
 caterer's
 caters
 catered
(10 rows)
</programlisting>

<programlisting>
 Limit  (cost=11583.61..11583.64 rows=10 width=32) (actual time=1431.591..1431.594 rows=10.00 loops=1)
   -&gt;  Sort  (cost=11583.61..11804.76 rows=88459 width=32) (actual time=1431.589..1431.591 rows=10.00 loops=1)
         Sort Key: ((word &lt;-&gt; 'caterpiler'::text))
         Sort Method: top-N heapsort  Memory: 25kB
         -&gt;  Foreign Scan on words  (cost=0.00..9672.05 rows=88459 width=32) (actual time=0.057..1286.455 rows=479829.00 loops=1)
               Foreign File: /usr/share/dict/words
               Foreign File Size: 4953699
 Planning time: 0.128 ms
 Execution time: 1431.679 ms
</programlisting>

    Using the materialized view:

<programlisting>
 Limit  (cost=0.29..1.06 rows=10 width=10) (actual time=187.222..188.257 rows=10.00 loops=1)
   -&gt;  Index Scan using wrd_trgm on wrd  (cost=0.29..37020.87 rows=479829 width=10) (actual time=187.219..188.252 rows=10.00 loops=1)
         Order By: (word &lt;-&gt; 'caterpiler'::text)
         Index Searches: 1
 Planning time: 0.196 ms
 Execution time: 198.640 ms
</programlisting>

    If you can tolerate periodic update of the remote data to the local
    database, the performance benefit can be substantial.
</para>

</sect1>

<sect1 id="rules-update">
<title>Rules on <command>INSERT</command>, <command>UPDATE</command>, and <command>DELETE</command></title>

<indexterm zone="rules-update">
 <primary>rule</primary>
 <secondary sortas="INSERT">for

Title: Using Materialized Views for Faster Query Performance
Summary
This section demonstrates the performance benefits of using materialized views in PostgreSQL, particularly when accessing data from remote systems through foreign data wrappers. A spell-checking example is used to compare the performance of querying a foreign table directly using file_fdw versus querying a materialized view. The results show that using a materialized view can significantly improve query performance, with execution times reduced from hundreds of milliseconds to just a few milliseconds.