-> Index Scan using tenk2_unique2 on tenk2 t2 (cost=0.29..7.91 rows=1 width=244) (actual time=0.021..0.022 rows=1 loops=10)
Index Cond: (unique2 = t1.unique2)
Planning time: 0.181 ms
- Total runtime: 0.501 ms
+ Execution time: 0.501 ms
Note that the actual time
values are in milliseconds of
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=101 width=0) (actual time=0.049..0.049 rows=100 loops=1)
Index Cond: (unique1 < 100)
Planning time: 0.194 ms
- Total runtime: 8.008 ms
+ Execution time: 8.008 ms
The Sort node shows the sort method used (in particular, whether the sort
Filter: (ten < 7)
Rows Removed by Filter: 3000
Planning time: 0.083 ms
- Total runtime: 5.905 ms
+ Execution time: 5.905 ms
These counts can be particularly valuable for filter conditions applied at
Filter: (f1 @> '((0.5,2))'::polygon)
Rows Removed by Filter: 4
Planning time: 0.040 ms
- Total runtime: 0.083 ms
+ Execution time: 0.083 ms
The planner thinks (quite correctly) that this sample table is too small
Index Cond: (f1 @> '((0.5,2))'::polygon)
Rows Removed by Index Recheck: 1
Planning time: 0.034 ms
- Total runtime: 0.144 ms
+ Execution time: 0.144 ms
Here we can see that the index returned one candidate row, which was
Index Cond: (unique2 > 9000)
Buffers: shared hit=5
Planning time: 0.088 ms
- Total runtime: 0.423 ms
+ Execution time: 0.423 ms
The numbers provided by BUFFERS> help to identify which parts
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=101 width=0) (actual time=0.043..0.043 rows=100 loops=1)
Index Cond: (unique1 < 100)
Planning time: 0.079 ms
- Total runtime: 14.727 ms
+ Execution time: 14.727 ms
ROLLBACK;
- The Total runtime shown by EXPLAIN
+ The Execution time shown by EXPLAIN
ANALYZE includes executor start-up and shut-down time, as well
as the time to run any triggers that are fired, but it does not include
parsing, rewriting, or planning time.
The total time spent in each trigger
(either BEFORE> or AFTER>) is also shown separately.
Note that deferred constraint triggers will not be executed
- until end of transaction and are thus not shown at all by
+ until end of transaction and are thus not considered at all by
EXPLAIN ANALYZE.
Filter: (unique1 < 100)
Rows Removed by Filter: 287
Planning time: 0.096 ms
- Total runtime: 0.336 ms
+ Execution time: 0.336 ms
the estimated cost and row count for the Index Scan node are shown as
Another use for a materialized view is to allow faster access to data
- brought across from a remote system, through a foreign data wrapper.
+ brought across from a remote system through a foreign data wrapper.
A simple example using file_fdw is below, with timings,
but since this is using cache on the local system the performance
- difference on a foreign data wrapper to a remote system could be greater.
+ 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 file_fdw does
+ not support indexes; this advantage might not apply for other sorts of
+ foreign data access.
+
Setup:
CREATE SERVER local_file FOREIGN DATA WRAPPER file_fdw;
CREATE FOREIGN TABLE words (word text NOT NULL)
SERVER local_file
- OPTIONS (filename '/etc/dictionaries-common/words');
+ 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;
(1 row)
- The plan is:
+ With EXPLAIN ANALYZE>, we see:
- Aggregate (cost=4125.19..4125.20 rows=1 width=0) (actual time=26.013..26.014 rows=1 loops=1)
- -> Foreign Scan on words (cost=0.00..4124.70 rows=196 width=0) (actual time=26.011..26.011 rows=0 loops=1)
+ Aggregate (cost=21763.99..21764.00 rows=1 width=0) (actual time=188.180..188.181 rows=1 loops=1)
+ -> Foreign Scan on words (cost=0.00..21761.41 rows=1032 width=0) (actual time=188.177..188.177 rows=0 loops=1)
Filter: (word = 'caterpiler'::text)
- Rows Removed by Filter: 99171
- Foreign File: /etc/dictionaries-common/words
- Foreign File Size: 938848
- Total runtime: 26.081 ms
+ 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
If the materialized view is used instead, the query is much faster:
- Aggregate (cost=4.44..4.45 rows=1 width=0) (actual time=0.074..0.074 rows=1 loops=1)
- -> Index Only Scan using wrd_word on wrd (cost=0.42..4.44 rows=1 width=0) (actual time=0.071..0.071 rows=0 loops=1)
+ Aggregate (cost=4.44..4.45 rows=1 width=0) (actual time=0.042..0.042 rows=1 loops=1)
+ -> 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 loops=1)
Index Cond: (word = 'caterpiler'::text)
Heap Fetches: 0
- Total runtime: 0.119 ms
+ Planning time: 0.164 ms
+ Execution time: 0.117 ms
Either way, the word is spelled wrong, so let's look for what we might
- Limit (cost=2195.70..2195.72 rows=10 width=32) (actual time=218.904..218.906 rows=10 loops=1)
- -> Sort (cost=2195.70..2237.61 rows=16765 width=32) (actual time=218.902..218.904 rows=10 loops=1)
- Sort Key: ((word <-> 'caterpiler'::text))
+ Limit (cost=11583.61..11583.64 rows=10 width=32) (actual time=1431.591..1431.594 rows=10 loops=1)
+ -> Sort (cost=11583.61..11804.76 rows=88459 width=32) (actual time=1431.589..1431.591 rows=10 loops=1)
+ Sort Key: ((word <-> 'caterpiler'::text))
Sort Method: top-N heapsort Memory: 25kB
- -> Foreign Scan on words (cost=0.00..1833.41 rows=16765 width=32) (actual time=0.046..200.965 rows=99171 loops=1)
- Foreign File: /etc/dictionaries-common/words
- Foreign File Size: 938848
- Total runtime: 218.966 ms
+ -> Foreign Scan on words (cost=0.00..9672.05 rows=88459 width=32) (actual time=0.057..1286.455 rows=479829 loops=1)
+ Foreign File: /usr/share/dict/words
+ Foreign File Size: 4953699
+ Planning time: 0.128 ms
+ Execution time: 1431.679 ms
Using the materialized view:
- Limit (cost=0.28..1.02 rows=10 width=9) (actual time=24.916..25.079 rows=10 loops=1)
- -> Index Scan using wrd_trgm on wrd (cost=0.28..7383.70 rows=99171 width=9) (actual time=24.914..25.076 rows=10 loops=1)
- Order By: (word <-> 'caterpiler'::text)
- Total runtime: 25.884 ms
+ Limit (cost=0.29..1.06 rows=10 width=10) (actual time=187.222..188.257 rows=10 loops=1)
+ -> Index Scan using wrd_trgm on wrd (cost=0.29..37020.87 rows=479829 width=10) (actual time=187.219..188.252 rows=10 loops=1)
+ Order By: (word <-> 'caterpiler'::text)
+ Planning time: 0.196 ms
+ Execution time: 198.640 ms
If you can tolerate periodic update of the remote data to the local