mirror of
https://github.com/postgres/postgres.git
synced 2025-06-05 23:56:58 +03:00
Enable BUFFERS with EXPLAIN ANALYZE by default
The topic of turning EXPLAIN's BUFFERS option on with the ANALYZE option has come up a few times over the past few years. In many ways, doing this seems like a good idea as it may be more obvious to users why a given query is running more slowly than they might expect. Also, from my own (David's) personal experience, I've seen users posting to the mailing lists with two identical plans, one slow and one fast asking why their query is sometimes slow. In many cases, this is due to additional reads. Having BUFFERS on by default may help reduce some of these questions, and if not, make it more obvious to the user before they post, or save a round-trip to the mailing list when additional I/O effort is the cause of the slowness. The general consensus is that we want BUFFERS on by default with ANALYZE. However, there were more than zero concerns raised with doing so. The primary reason against is the additional verbosity, making it harder to read large plans. Another concern was that buffer information isn't always useful so may not make sense to have it on by default. It's currently December, so let's commit this to see if anyone comes forward with a strong objection against making this change. We have over half a year remaining in the v18 cycle where we could still easily consider reverting this if someone were to come forward with a convincing enough reason as to why doing this is a bad idea. There were two patches independently submitted to achieve this goal, one by me and the other by Guillaume. This commit is a mix of both of these patches with some additional work done by me to adjust various additional places in the documentation which include EXPLAIN ANALYZE output. Author: Guillaume Lelarge, David Rowley Reviewed-by: Robert Haas, Greg Sabino Mullane, Michael Christofides Discussion: https://postgr.es/m/CANNMO++W7MM8T0KyXN3ZheXXt-uLVM3aEtZd+WNfZ=obxffUiA@mail.gmail.com
This commit is contained in:
parent
0f5738202b
commit
c2a4078eba
@ -11553,7 +11553,7 @@ SELECT * FROM local_tbl, async_pt WHERE local_tbl.a = async_pt.a AND local_tbl.c
|
|||||||
Filter: (async_pt_3.a = local_tbl.a)
|
Filter: (async_pt_3.a = local_tbl.a)
|
||||||
(15 rows)
|
(15 rows)
|
||||||
|
|
||||||
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF)
|
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF, BUFFERS OFF)
|
||||||
SELECT * FROM local_tbl, async_pt WHERE local_tbl.a = async_pt.a AND local_tbl.c = 'bar';
|
SELECT * FROM local_tbl, async_pt WHERE local_tbl.a = async_pt.a AND local_tbl.c = 'bar';
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@ -11799,7 +11799,7 @@ SELECT * FROM local_tbl t1 LEFT JOIN (SELECT *, (SELECT count(*) FROM async_pt W
|
|||||||
Remote SQL: SELECT a, b, c FROM public.base_tbl2 WHERE ((a < 3000))
|
Remote SQL: SELECT a, b, c FROM public.base_tbl2 WHERE ((a < 3000))
|
||||||
(20 rows)
|
(20 rows)
|
||||||
|
|
||||||
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF)
|
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF, BUFFERS OFF)
|
||||||
SELECT * FROM local_tbl t1 LEFT JOIN (SELECT *, (SELECT count(*) FROM async_pt WHERE a < 3000) FROM async_pt WHERE a < 3000) t2 ON t1.a = t2.a;
|
SELECT * FROM local_tbl t1 LEFT JOIN (SELECT *, (SELECT count(*) FROM async_pt WHERE a < 3000) FROM async_pt WHERE a < 3000) t2 ON t1.a = t2.a;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-----------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------
|
||||||
@ -11843,7 +11843,7 @@ SELECT * FROM async_pt t1 WHERE t1.b === 505 LIMIT 1;
|
|||||||
Filter: (t1_3.b === 505)
|
Filter: (t1_3.b === 505)
|
||||||
(14 rows)
|
(14 rows)
|
||||||
|
|
||||||
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF)
|
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF, BUFFERS OFF)
|
||||||
SELECT * FROM async_pt t1 WHERE t1.b === 505 LIMIT 1;
|
SELECT * FROM async_pt t1 WHERE t1.b === 505 LIMIT 1;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
@ -12003,7 +12003,7 @@ DELETE FROM async_pt WHERE b = 0 RETURNING *;
|
|||||||
DELETE FROM async_p1;
|
DELETE FROM async_p1;
|
||||||
DELETE FROM async_p2;
|
DELETE FROM async_p2;
|
||||||
DELETE FROM async_p3;
|
DELETE FROM async_p3;
|
||||||
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF)
|
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF, BUFFERS OFF)
|
||||||
SELECT * FROM async_pt;
|
SELECT * FROM async_pt;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
|
@ -3904,7 +3904,7 @@ ALTER FOREIGN TABLE async_p2 OPTIONS (use_remote_estimate 'true');
|
|||||||
|
|
||||||
EXPLAIN (VERBOSE, COSTS OFF)
|
EXPLAIN (VERBOSE, COSTS OFF)
|
||||||
SELECT * FROM local_tbl, async_pt WHERE local_tbl.a = async_pt.a AND local_tbl.c = 'bar';
|
SELECT * FROM local_tbl, async_pt WHERE local_tbl.a = async_pt.a AND local_tbl.c = 'bar';
|
||||||
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF)
|
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF, BUFFERS OFF)
|
||||||
SELECT * FROM local_tbl, async_pt WHERE local_tbl.a = async_pt.a AND local_tbl.c = 'bar';
|
SELECT * FROM local_tbl, async_pt WHERE local_tbl.a = async_pt.a AND local_tbl.c = 'bar';
|
||||||
SELECT * FROM local_tbl, async_pt WHERE local_tbl.a = async_pt.a AND local_tbl.c = 'bar';
|
SELECT * FROM local_tbl, async_pt WHERE local_tbl.a = async_pt.a AND local_tbl.c = 'bar';
|
||||||
|
|
||||||
@ -3979,13 +3979,13 @@ ANALYZE local_tbl;
|
|||||||
|
|
||||||
EXPLAIN (VERBOSE, COSTS OFF)
|
EXPLAIN (VERBOSE, COSTS OFF)
|
||||||
SELECT * FROM local_tbl t1 LEFT JOIN (SELECT *, (SELECT count(*) FROM async_pt WHERE a < 3000) FROM async_pt WHERE a < 3000) t2 ON t1.a = t2.a;
|
SELECT * FROM local_tbl t1 LEFT JOIN (SELECT *, (SELECT count(*) FROM async_pt WHERE a < 3000) FROM async_pt WHERE a < 3000) t2 ON t1.a = t2.a;
|
||||||
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF)
|
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF, BUFFERS OFF)
|
||||||
SELECT * FROM local_tbl t1 LEFT JOIN (SELECT *, (SELECT count(*) FROM async_pt WHERE a < 3000) FROM async_pt WHERE a < 3000) t2 ON t1.a = t2.a;
|
SELECT * FROM local_tbl t1 LEFT JOIN (SELECT *, (SELECT count(*) FROM async_pt WHERE a < 3000) FROM async_pt WHERE a < 3000) t2 ON t1.a = t2.a;
|
||||||
SELECT * FROM local_tbl t1 LEFT JOIN (SELECT *, (SELECT count(*) FROM async_pt WHERE a < 3000) FROM async_pt WHERE a < 3000) t2 ON t1.a = t2.a;
|
SELECT * FROM local_tbl t1 LEFT JOIN (SELECT *, (SELECT count(*) FROM async_pt WHERE a < 3000) FROM async_pt WHERE a < 3000) t2 ON t1.a = t2.a;
|
||||||
|
|
||||||
EXPLAIN (VERBOSE, COSTS OFF)
|
EXPLAIN (VERBOSE, COSTS OFF)
|
||||||
SELECT * FROM async_pt t1 WHERE t1.b === 505 LIMIT 1;
|
SELECT * FROM async_pt t1 WHERE t1.b === 505 LIMIT 1;
|
||||||
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF)
|
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF, BUFFERS OFF)
|
||||||
SELECT * FROM async_pt t1 WHERE t1.b === 505 LIMIT 1;
|
SELECT * FROM async_pt t1 WHERE t1.b === 505 LIMIT 1;
|
||||||
SELECT * FROM async_pt t1 WHERE t1.b === 505 LIMIT 1;
|
SELECT * FROM async_pt t1 WHERE t1.b === 505 LIMIT 1;
|
||||||
|
|
||||||
@ -4037,7 +4037,7 @@ DELETE FROM async_p1;
|
|||||||
DELETE FROM async_p2;
|
DELETE FROM async_p2;
|
||||||
DELETE FROM async_p3;
|
DELETE FROM async_p3;
|
||||||
|
|
||||||
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF)
|
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF, BUFFERS OFF)
|
||||||
SELECT * FROM async_pt;
|
SELECT * FROM async_pt;
|
||||||
|
|
||||||
-- Clean up
|
-- Clean up
|
||||||
|
@ -121,9 +121,10 @@ SELECT 10000000
|
|||||||
Seq Scan on tbloom (cost=0.00..213744.00 rows=250 width=24) (actual time=357.059..357.059 rows=0 loops=1)
|
Seq Scan on tbloom (cost=0.00..213744.00 rows=250 width=24) (actual time=357.059..357.059 rows=0 loops=1)
|
||||||
Filter: ((i2 = 898732) AND (i5 = 123451))
|
Filter: ((i2 = 898732) AND (i5 = 123451))
|
||||||
Rows Removed by Filter: 10000000
|
Rows Removed by Filter: 10000000
|
||||||
|
Buffers: shared hit=63744
|
||||||
Planning Time: 0.346 ms
|
Planning Time: 0.346 ms
|
||||||
Execution Time: 357.076 ms
|
Execution Time: 357.076 ms
|
||||||
(5 rows)
|
(6 rows)
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@ -144,9 +145,10 @@ CREATE INDEX
|
|||||||
Seq Scan on tbloom (cost=0.00..213744.00 rows=2 width=24) (actual time=351.016..351.017 rows=0 loops=1)
|
Seq Scan on tbloom (cost=0.00..213744.00 rows=2 width=24) (actual time=351.016..351.017 rows=0 loops=1)
|
||||||
Filter: ((i2 = 898732) AND (i5 = 123451))
|
Filter: ((i2 = 898732) AND (i5 = 123451))
|
||||||
Rows Removed by Filter: 10000000
|
Rows Removed by Filter: 10000000
|
||||||
|
Buffers: shared hit=63744
|
||||||
Planning Time: 0.138 ms
|
Planning Time: 0.138 ms
|
||||||
Execution Time: 351.035 ms
|
Execution Time: 351.035 ms
|
||||||
(5 rows)
|
(6 rows)
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@ -168,11 +170,13 @@ CREATE INDEX
|
|||||||
Recheck Cond: ((i2 = 898732) AND (i5 = 123451))
|
Recheck Cond: ((i2 = 898732) AND (i5 = 123451))
|
||||||
Rows Removed by Index Recheck: 2300
|
Rows Removed by Index Recheck: 2300
|
||||||
Heap Blocks: exact=2256
|
Heap Blocks: exact=2256
|
||||||
|
Buffers: shared hit=21864
|
||||||
-> Bitmap Index Scan on bloomidx (cost=0.00..178436.00 rows=1 width=0) (actual time=20.005..20.005 rows=2300 loops=1)
|
-> Bitmap Index Scan on bloomidx (cost=0.00..178436.00 rows=1 width=0) (actual time=20.005..20.005 rows=2300 loops=1)
|
||||||
Index Cond: ((i2 = 898732) AND (i5 = 123451))
|
Index Cond: ((i2 = 898732) AND (i5 = 123451))
|
||||||
|
Buffers: shared hit=19608
|
||||||
Planning Time: 0.099 ms
|
Planning Time: 0.099 ms
|
||||||
Execution Time: 22.632 ms
|
Execution Time: 22.632 ms
|
||||||
(8 rows)
|
(10 rows)
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@ -199,14 +203,18 @@ CREATE INDEX
|
|||||||
-------------------------------------------------------------------&zwsp;--------------------------------------------------------
|
-------------------------------------------------------------------&zwsp;--------------------------------------------------------
|
||||||
Bitmap Heap Scan on tbloom (cost=9.29..13.30 rows=1 width=24) (actual time=0.032..0.033 rows=0 loops=1)
|
Bitmap Heap Scan on tbloom (cost=9.29..13.30 rows=1 width=24) (actual time=0.032..0.033 rows=0 loops=1)
|
||||||
Recheck Cond: ((i5 = 123451) AND (i2 = 898732))
|
Recheck Cond: ((i5 = 123451) AND (i2 = 898732))
|
||||||
|
Buffers: shared read=6
|
||||||
-> BitmapAnd (cost=9.29..9.29 rows=1 width=0) (actual time=0.047..0.047 rows=0 loops=1)
|
-> BitmapAnd (cost=9.29..9.29 rows=1 width=0) (actual time=0.047..0.047 rows=0 loops=1)
|
||||||
|
Buffers: shared hit=6
|
||||||
-> Bitmap Index Scan on btreeidx5 (cost=0.00..4.52 rows=11 width=0) (actual time=0.026..0.026 rows=7 loops=1)
|
-> Bitmap Index Scan on btreeidx5 (cost=0.00..4.52 rows=11 width=0) (actual time=0.026..0.026 rows=7 loops=1)
|
||||||
Index Cond: (i5 = 123451)
|
Index Cond: (i5 = 123451)
|
||||||
|
Buffers: shared hit=3
|
||||||
-> Bitmap Index Scan on btreeidx2 (cost=0.00..4.52 rows=11 width=0) (actual time=0.007..0.007 rows=8 loops=1)
|
-> Bitmap Index Scan on btreeidx2 (cost=0.00..4.52 rows=11 width=0) (actual time=0.007..0.007 rows=8 loops=1)
|
||||||
Index Cond: (i2 = 898732)
|
Index Cond: (i2 = 898732)
|
||||||
|
Buffers: shared hit=3
|
||||||
Planning Time: 0.264 ms
|
Planning Time: 0.264 ms
|
||||||
Execution Time: 0.047 ms
|
Execution Time: 0.047 ms
|
||||||
(9 rows)
|
(13 rows)
|
||||||
</programlisting>
|
</programlisting>
|
||||||
Although this query runs much faster than with either of the single
|
Although this query runs much faster than with either of the single
|
||||||
indexes, we pay a penalty in index size. Each of the single-column
|
indexes, we pay a penalty in index size. Each of the single-column
|
||||||
|
@ -149,10 +149,11 @@
|
|||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------------&zwsp;------------------------------------------
|
-------------------------------------------------------------------&zwsp;------------------------------------------
|
||||||
Aggregate (cost=16.27..16.29 rows=1 width=8) (actual time=0.303..0.303 rows=1 loops=1)
|
Aggregate (cost=16.27..16.29 rows=1 width=8) (actual time=0.303..0.303 rows=1 loops=1)
|
||||||
|
Buffers: shared hit=14
|
||||||
-> Seq Scan on pg_class (cost=0.00..15.42 rows=342 width=4) (actual time=0.017..0.111 rows=356 loops=1)
|
-> Seq Scan on pg_class (cost=0.00..15.42 rows=342 width=4) (actual time=0.017..0.111 rows=356 loops=1)
|
||||||
|
Buffers: shared hit=14
|
||||||
Planning Time: 0.116 ms
|
Planning Time: 0.116 ms
|
||||||
Execution Time: 0.365 ms
|
Execution Time: 0.365 ms
|
||||||
(4 rows)
|
|
||||||
</screen>
|
</screen>
|
||||||
Given the cost of the plan, it is entirely reasonable that no
|
Given the cost of the plan, it is entirely reasonable that no
|
||||||
<acronym>JIT</acronym> was used; the cost of <acronym>JIT</acronym> would
|
<acronym>JIT</acronym> was used; the cost of <acronym>JIT</acronym> would
|
||||||
@ -165,7 +166,9 @@ SET
|
|||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------------&zwsp;------------------------------------------
|
-------------------------------------------------------------------&zwsp;------------------------------------------
|
||||||
Aggregate (cost=16.27..16.29 rows=1 width=8) (actual time=6.049..6.049 rows=1 loops=1)
|
Aggregate (cost=16.27..16.29 rows=1 width=8) (actual time=6.049..6.049 rows=1 loops=1)
|
||||||
|
Buffers: shared hit=14
|
||||||
-> Seq Scan on pg_class (cost=0.00..15.42 rows=342 width=4) (actual time=0.019..0.052 rows=356 loops=1)
|
-> Seq Scan on pg_class (cost=0.00..15.42 rows=342 width=4) (actual time=0.019..0.052 rows=356 loops=1)
|
||||||
|
Buffers: shared hit=14
|
||||||
Planning Time: 0.133 ms
|
Planning Time: 0.133 ms
|
||||||
JIT:
|
JIT:
|
||||||
Functions: 3
|
Functions: 3
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
Examples in this section are drawn from the regression test database
|
Examples in this section are drawn from the regression test database
|
||||||
after doing a <command>VACUUM ANALYZE</command>, using v17 development sources.
|
after doing a <command>VACUUM ANALYZE</command>, using v18 development sources.
|
||||||
You should be able to get similar results if you try the examples
|
You should be able to get similar results if you try the examples
|
||||||
yourself, but your estimated costs and row counts might vary slightly
|
yourself, but your estimated costs and row counts might vary slightly
|
||||||
because <command>ANALYZE</command>'s statistics are random samples rather
|
because <command>ANALYZE</command>'s statistics are random samples rather
|
||||||
@ -722,13 +722,19 @@ WHERE t1.unique1 < 10 AND t1.unique2 = t2.unique2;
|
|||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------------&zwsp;--------------------------------------------------------------
|
-------------------------------------------------------------------&zwsp;--------------------------------------------------------------
|
||||||
Nested Loop (cost=4.65..118.50 rows=10 width=488) (actual time=0.017..0.051 rows=10 loops=1)
|
Nested Loop (cost=4.65..118.50 rows=10 width=488) (actual time=0.017..0.051 rows=10 loops=1)
|
||||||
|
Buffers: shared hit=36 read=6
|
||||||
-> Bitmap Heap Scan on tenk1 t1 (cost=4.36..39.38 rows=10 width=244) (actual time=0.009..0.017 rows=10 loops=1)
|
-> Bitmap Heap Scan on tenk1 t1 (cost=4.36..39.38 rows=10 width=244) (actual time=0.009..0.017 rows=10 loops=1)
|
||||||
Recheck Cond: (unique1 < 10)
|
Recheck Cond: (unique1 < 10)
|
||||||
Heap Blocks: exact=10
|
Heap Blocks: exact=10
|
||||||
|
Buffers: shared hit=3 read=5 written=4
|
||||||
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..4.36 rows=10 width=0) (actual time=0.004..0.004 rows=10 loops=1)
|
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..4.36 rows=10 width=0) (actual time=0.004..0.004 rows=10 loops=1)
|
||||||
Index Cond: (unique1 < 10)
|
Index Cond: (unique1 < 10)
|
||||||
|
Buffers: shared hit=2
|
||||||
-> Index Scan using tenk2_unique2 on tenk2 t2 (cost=0.29..7.90 rows=1 width=244) (actual time=0.003..0.003 rows=1 loops=10)
|
-> Index Scan using tenk2_unique2 on tenk2 t2 (cost=0.29..7.90 rows=1 width=244) (actual time=0.003..0.003 rows=1 loops=10)
|
||||||
Index Cond: (unique2 = t1.unique2)
|
Index Cond: (unique2 = t1.unique2)
|
||||||
|
Buffers: shared hit=24 read=6
|
||||||
|
Planning:
|
||||||
|
Buffers: shared hit=15 dirtied=9
|
||||||
Planning Time: 0.485 ms
|
Planning Time: 0.485 ms
|
||||||
Execution Time: 0.073 ms
|
Execution Time: 0.073 ms
|
||||||
</screen>
|
</screen>
|
||||||
@ -769,16 +775,24 @@ WHERE t1.unique1 < 100 AND t1.unique2 = t2.unique2 ORDER BY t1.fivethous;
|
|||||||
Sort (cost=713.05..713.30 rows=100 width=488) (actual time=2.995..3.002 rows=100 loops=1)
|
Sort (cost=713.05..713.30 rows=100 width=488) (actual time=2.995..3.002 rows=100 loops=1)
|
||||||
Sort Key: t1.fivethous
|
Sort Key: t1.fivethous
|
||||||
Sort Method: quicksort Memory: 74kB
|
Sort Method: quicksort Memory: 74kB
|
||||||
|
Buffers: shared hit=440
|
||||||
-> Hash Join (cost=226.23..709.73 rows=100 width=488) (actual time=0.515..2.920 rows=100 loops=1)
|
-> Hash Join (cost=226.23..709.73 rows=100 width=488) (actual time=0.515..2.920 rows=100 loops=1)
|
||||||
Hash Cond: (t2.unique2 = t1.unique2)
|
Hash Cond: (t2.unique2 = t1.unique2)
|
||||||
|
Buffers: shared hit=437
|
||||||
-> Seq Scan on tenk2 t2 (cost=0.00..445.00 rows=10000 width=244) (actual time=0.026..1.790 rows=10000 loops=1)
|
-> Seq Scan on tenk2 t2 (cost=0.00..445.00 rows=10000 width=244) (actual time=0.026..1.790 rows=10000 loops=1)
|
||||||
|
Buffers: shared hit=345
|
||||||
-> Hash (cost=224.98..224.98 rows=100 width=244) (actual time=0.476..0.477 rows=100 loops=1)
|
-> Hash (cost=224.98..224.98 rows=100 width=244) (actual time=0.476..0.477 rows=100 loops=1)
|
||||||
Buckets: 1024 Batches: 1 Memory Usage: 35kB
|
Buckets: 1024 Batches: 1 Memory Usage: 35kB
|
||||||
|
Buffers: shared hit=92
|
||||||
-> Bitmap Heap Scan on tenk1 t1 (cost=5.06..224.98 rows=100 width=244) (actual time=0.030..0.450 rows=100 loops=1)
|
-> Bitmap Heap Scan on tenk1 t1 (cost=5.06..224.98 rows=100 width=244) (actual time=0.030..0.450 rows=100 loops=1)
|
||||||
Recheck Cond: (unique1 < 100)
|
Recheck Cond: (unique1 < 100)
|
||||||
Heap Blocks: exact=90
|
Heap Blocks: exact=90
|
||||||
|
Buffers: shared hit=92
|
||||||
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=100 width=0) (actual time=0.013..0.013 rows=100 loops=1)
|
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=100 width=0) (actual time=0.013..0.013 rows=100 loops=1)
|
||||||
Index Cond: (unique1 < 100)
|
Index Cond: (unique1 < 100)
|
||||||
|
Buffers: shared hit=2
|
||||||
|
Planning:
|
||||||
|
Buffers: shared hit=12
|
||||||
Planning Time: 0.187 ms
|
Planning Time: 0.187 ms
|
||||||
Execution Time: 3.036 ms
|
Execution Time: 3.036 ms
|
||||||
</screen>
|
</screen>
|
||||||
@ -803,6 +817,7 @@ EXPLAIN ANALYZE SELECT * FROM tenk1 WHERE ten < 7;
|
|||||||
Seq Scan on tenk1 (cost=0.00..470.00 rows=7000 width=244) (actual time=0.030..1.995 rows=7000 loops=1)
|
Seq Scan on tenk1 (cost=0.00..470.00 rows=7000 width=244) (actual time=0.030..1.995 rows=7000 loops=1)
|
||||||
Filter: (ten < 7)
|
Filter: (ten < 7)
|
||||||
Rows Removed by Filter: 3000
|
Rows Removed by Filter: 3000
|
||||||
|
Buffers: shared hit=345
|
||||||
Planning Time: 0.102 ms
|
Planning Time: 0.102 ms
|
||||||
Execution Time: 2.145 ms
|
Execution Time: 2.145 ms
|
||||||
</screen>
|
</screen>
|
||||||
@ -826,6 +841,7 @@ EXPLAIN ANALYZE SELECT * FROM polygon_tbl WHERE f1 @> polygon '(0.5,2.0)';
|
|||||||
Seq Scan on polygon_tbl (cost=0.00..1.09 rows=1 width=85) (actual time=0.023..0.023 rows=0 loops=1)
|
Seq Scan on polygon_tbl (cost=0.00..1.09 rows=1 width=85) (actual time=0.023..0.023 rows=0 loops=1)
|
||||||
Filter: (f1 @> '((0.5,2))'::polygon)
|
Filter: (f1 @> '((0.5,2))'::polygon)
|
||||||
Rows Removed by Filter: 7
|
Rows Removed by Filter: 7
|
||||||
|
Buffers: shared hit=1
|
||||||
Planning Time: 0.039 ms
|
Planning Time: 0.039 ms
|
||||||
Execution Time: 0.033 ms
|
Execution Time: 0.033 ms
|
||||||
</screen>
|
</screen>
|
||||||
@ -845,6 +861,7 @@ EXPLAIN ANALYZE SELECT * FROM polygon_tbl WHERE f1 @> polygon '(0.5,2.0)';
|
|||||||
Index Scan using gpolygonind on polygon_tbl (cost=0.13..8.15 rows=1 width=85) (actual time=0.074..0.074 rows=0 loops=1)
|
Index Scan using gpolygonind on polygon_tbl (cost=0.13..8.15 rows=1 width=85) (actual time=0.074..0.074 rows=0 loops=1)
|
||||||
Index Cond: (f1 @> '((0.5,2))'::polygon)
|
Index Cond: (f1 @> '((0.5,2))'::polygon)
|
||||||
Rows Removed by Index Recheck: 1
|
Rows Removed by Index Recheck: 1
|
||||||
|
Buffers: shared hit=1
|
||||||
Planning Time: 0.039 ms
|
Planning Time: 0.039 ms
|
||||||
Execution Time: 0.098 ms
|
Execution Time: 0.098 ms
|
||||||
</screen>
|
</screen>
|
||||||
@ -857,34 +874,31 @@ EXPLAIN ANALYZE SELECT * FROM polygon_tbl WHERE f1 @> polygon '(0.5,2.0)';
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
<command>EXPLAIN</command> has a <literal>BUFFERS</literal> option that can be used with
|
<command>EXPLAIN</command> has a <literal>BUFFERS</literal> option which
|
||||||
<literal>ANALYZE</literal> to get even more run time statistics:
|
provides additional detail about I/O operations performed during the
|
||||||
|
planning and execution of the given query. The buffer numbers displayed
|
||||||
|
show the count of the non-distinct buffers hit, read, dirtied, and written
|
||||||
|
for the given node and all of its child nodes. The
|
||||||
|
<literal>ANALYZE</literal> option implicitly enables the
|
||||||
|
<literal>BUFFERS</literal> option. If this
|
||||||
|
is undesired, <literal>BUFFERS</literal> may be explicitly disabled:
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000;
|
EXPLAIN (ANALYZE, BUFFERS OFF) SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000;
|
||||||
|
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------------&zwsp;--------------------------------------------------------------
|
-------------------------------------------------------------------&zwsp;--------------------------------------------------------------
|
||||||
Bitmap Heap Scan on tenk1 (cost=25.07..60.11 rows=10 width=244) (actual time=0.105..0.114 rows=10 loops=1)
|
Bitmap Heap Scan on tenk1 (cost=25.07..60.11 rows=10 width=244) (actual time=0.105..0.114 rows=10 loops=1)
|
||||||
Recheck Cond: ((unique1 < 100) AND (unique2 > 9000))
|
Recheck Cond: ((unique1 < 100) AND (unique2 > 9000))
|
||||||
Heap Blocks: exact=10
|
Heap Blocks: exact=10
|
||||||
Buffers: shared hit=14 read=3
|
|
||||||
-> BitmapAnd (cost=25.07..25.07 rows=10 width=0) (actual time=0.100..0.101 rows=0 loops=1)
|
-> BitmapAnd (cost=25.07..25.07 rows=10 width=0) (actual time=0.100..0.101 rows=0 loops=1)
|
||||||
Buffers: shared hit=4 read=3
|
|
||||||
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=100 width=0) (actual time=0.027..0.027 rows=100 loops=1)
|
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=100 width=0) (actual time=0.027..0.027 rows=100 loops=1)
|
||||||
Index Cond: (unique1 < 100)
|
Index Cond: (unique1 < 100)
|
||||||
Buffers: shared hit=2
|
|
||||||
-> Bitmap Index Scan on tenk1_unique2 (cost=0.00..19.78 rows=999 width=0) (actual time=0.070..0.070 rows=999 loops=1)
|
-> Bitmap Index Scan on tenk1_unique2 (cost=0.00..19.78 rows=999 width=0) (actual time=0.070..0.070 rows=999 loops=1)
|
||||||
Index Cond: (unique2 > 9000)
|
Index Cond: (unique2 > 9000)
|
||||||
Buffers: shared hit=2 read=3
|
|
||||||
Planning:
|
|
||||||
Buffers: shared hit=3
|
|
||||||
Planning Time: 0.162 ms
|
Planning Time: 0.162 ms
|
||||||
Execution Time: 0.143 ms
|
Execution Time: 0.143 ms
|
||||||
</screen>
|
</screen>
|
||||||
|
|
||||||
The numbers provided by <literal>BUFFERS</literal> help to identify which parts
|
|
||||||
of the query are the most I/O-intensive.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -906,8 +920,10 @@ EXPLAIN ANALYZE UPDATE tenk1 SET hundred = hundred + 1 WHERE unique1 < 100;
|
|||||||
-> Bitmap Heap Scan on tenk1 (cost=5.06..225.23 rows=100 width=10) (actual time=0.065..0.141 rows=100 loops=1)
|
-> Bitmap Heap Scan on tenk1 (cost=5.06..225.23 rows=100 width=10) (actual time=0.065..0.141 rows=100 loops=1)
|
||||||
Recheck Cond: (unique1 < 100)
|
Recheck Cond: (unique1 < 100)
|
||||||
Heap Blocks: exact=90
|
Heap Blocks: exact=90
|
||||||
|
Buffers: shared hit=4 read=2
|
||||||
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=100 width=0) (actual time=0.031..0.031 rows=100 loops=1)
|
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=100 width=0) (actual time=0.031..0.031 rows=100 loops=1)
|
||||||
Index Cond: (unique1 < 100)
|
Index Cond: (unique1 < 100)
|
||||||
|
Buffers: shared read=2
|
||||||
Planning Time: 0.151 ms
|
Planning Time: 0.151 ms
|
||||||
Execution Time: 1.856 ms
|
Execution Time: 1.856 ms
|
||||||
|
|
||||||
@ -1040,10 +1056,12 @@ EXPLAIN ANALYZE SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000
|
|||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------------&zwsp;------------------------------------------------------------
|
-------------------------------------------------------------------&zwsp;------------------------------------------------------------
|
||||||
Limit (cost=0.29..14.33 rows=2 width=244) (actual time=0.051..0.071 rows=2 loops=1)
|
Limit (cost=0.29..14.33 rows=2 width=244) (actual time=0.051..0.071 rows=2 loops=1)
|
||||||
|
Buffers: shared hit=16
|
||||||
-> Index Scan using tenk1_unique2 on tenk1 (cost=0.29..70.50 rows=10 width=244) (actual time=0.051..0.070 rows=2 loops=1)
|
-> Index Scan using tenk1_unique2 on tenk1 (cost=0.29..70.50 rows=10 width=244) (actual time=0.051..0.070 rows=2 loops=1)
|
||||||
Index Cond: (unique2 > 9000)
|
Index Cond: (unique2 > 9000)
|
||||||
Filter: (unique1 < 100)
|
Filter: (unique1 < 100)
|
||||||
Rows Removed by Filter: 287
|
Rows Removed by Filter: 287
|
||||||
|
Buffers: shared hit=16
|
||||||
Planning Time: 0.077 ms
|
Planning Time: 0.077 ms
|
||||||
Execution Time: 0.086 ms
|
Execution Time: 0.086 ms
|
||||||
</screen>
|
</screen>
|
||||||
|
@ -489,7 +489,7 @@ SELECT relpages, reltuples FROM pg_class WHERE relname = 't';
|
|||||||
condition on the <structfield>a</structfield> column:
|
condition on the <structfield>a</structfield> column:
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1;
|
EXPLAIN (ANALYZE, TIMING OFF, BUFFERS OFF) SELECT * FROM t WHERE a = 1;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------------&zwsp;------------
|
-------------------------------------------------------------------&zwsp;------------
|
||||||
Seq Scan on t (cost=0.00..170.00 rows=100 width=8) (actual rows=100 loops=1)
|
Seq Scan on t (cost=0.00..170.00 rows=100 width=8) (actual rows=100 loops=1)
|
||||||
@ -506,7 +506,7 @@ EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1;
|
|||||||
condition on both columns, combining them with <literal>AND</literal>:
|
condition on both columns, combining them with <literal>AND</literal>:
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1 AND b = 1;
|
EXPLAIN (ANALYZE, TIMING OFF, BUFFERS OFF) SELECT * FROM t WHERE a = 1 AND b = 1;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------------&zwsp;----------
|
-------------------------------------------------------------------&zwsp;----------
|
||||||
Seq Scan on t (cost=0.00..195.00 rows=1 width=8) (actual rows=100 loops=1)
|
Seq Scan on t (cost=0.00..195.00 rows=1 width=8) (actual rows=100 loops=1)
|
||||||
@ -530,7 +530,7 @@ EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1 AND b = 1;
|
|||||||
<programlisting>
|
<programlisting>
|
||||||
CREATE STATISTICS stts (dependencies) ON a, b FROM t;
|
CREATE STATISTICS stts (dependencies) ON a, b FROM t;
|
||||||
ANALYZE t;
|
ANALYZE t;
|
||||||
EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1 AND b = 1;
|
EXPLAIN (ANALYZE, TIMING OFF, BUFFERS OFF) SELECT * FROM t WHERE a = 1 AND b = 1;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------------&zwsp;------------
|
-------------------------------------------------------------------&zwsp;------------
|
||||||
Seq Scan on t (cost=0.00..195.00 rows=100 width=8) (actual rows=100 loops=1)
|
Seq Scan on t (cost=0.00..195.00 rows=100 width=8) (actual rows=100 loops=1)
|
||||||
@ -551,7 +551,7 @@ EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1 AND b = 1;
|
|||||||
estimated number of rows returned by the HashAggregate node) is very
|
estimated number of rows returned by the HashAggregate node) is very
|
||||||
accurate:
|
accurate:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
EXPLAIN (ANALYZE, TIMING OFF) SELECT COUNT(*) FROM t GROUP BY a;
|
EXPLAIN (ANALYZE, TIMING OFF, BUFFERS OFF) SELECT COUNT(*) FROM t GROUP BY a;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------------&zwsp;----------------------
|
-------------------------------------------------------------------&zwsp;----------------------
|
||||||
HashAggregate (cost=195.00..196.00 rows=100 width=12) (actual rows=100 loops=1)
|
HashAggregate (cost=195.00..196.00 rows=100 width=12) (actual rows=100 loops=1)
|
||||||
@ -562,7 +562,7 @@ EXPLAIN (ANALYZE, TIMING OFF) SELECT COUNT(*) FROM t GROUP BY a;
|
|||||||
groups in a query with two columns in <command>GROUP BY</command>, as
|
groups in a query with two columns in <command>GROUP BY</command>, as
|
||||||
in the following example, is off by an order of magnitude:
|
in the following example, is off by an order of magnitude:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
EXPLAIN (ANALYZE, TIMING OFF) SELECT COUNT(*) FROM t GROUP BY a, b;
|
EXPLAIN (ANALYZE, TIMING OFF, BUFFERS OFF) SELECT COUNT(*) FROM t GROUP BY a, b;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------------&zwsp;-------------------------
|
-------------------------------------------------------------------&zwsp;-------------------------
|
||||||
HashAggregate (cost=220.00..230.00 rows=1000 width=16) (actual rows=100 loops=1)
|
HashAggregate (cost=220.00..230.00 rows=1000 width=16) (actual rows=100 loops=1)
|
||||||
@ -575,7 +575,7 @@ EXPLAIN (ANALYZE, TIMING OFF) SELECT COUNT(*) FROM t GROUP BY a, b;
|
|||||||
DROP STATISTICS stts;
|
DROP STATISTICS stts;
|
||||||
CREATE STATISTICS stts (dependencies, ndistinct) ON a, b FROM t;
|
CREATE STATISTICS stts (dependencies, ndistinct) ON a, b FROM t;
|
||||||
ANALYZE t;
|
ANALYZE t;
|
||||||
EXPLAIN (ANALYZE, TIMING OFF) SELECT COUNT(*) FROM t GROUP BY a, b;
|
EXPLAIN (ANALYZE, TIMING OFF, BUFFERS OFF) SELECT COUNT(*) FROM t GROUP BY a, b;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------------&zwsp;-------------------------
|
-------------------------------------------------------------------&zwsp;-------------------------
|
||||||
HashAggregate (cost=220.00..221.00 rows=100 width=16) (actual rows=100 loops=1)
|
HashAggregate (cost=220.00..221.00 rows=100 width=16) (actual rows=100 loops=1)
|
||||||
@ -615,7 +615,7 @@ EXPLAIN (ANALYZE, TIMING OFF) SELECT COUNT(*) FROM t GROUP BY a, b;
|
|||||||
DROP STATISTICS stts;
|
DROP STATISTICS stts;
|
||||||
CREATE STATISTICS stts2 (mcv) ON a, b FROM t;
|
CREATE STATISTICS stts2 (mcv) ON a, b FROM t;
|
||||||
ANALYZE t;
|
ANALYZE t;
|
||||||
EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1 AND b = 1;
|
EXPLAIN (ANALYZE, TIMING OFF, BUFFERS OFF) SELECT * FROM t WHERE a = 1 AND b = 1;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------------&zwsp;------------
|
-------------------------------------------------------------------&zwsp;------------
|
||||||
Seq Scan on t (cost=0.00..195.00 rows=100 width=8) (actual rows=100 loops=1)
|
Seq Scan on t (cost=0.00..195.00 rows=100 width=8) (actual rows=100 loops=1)
|
||||||
@ -672,7 +672,7 @@ SELECT m.* FROM pg_statistic_ext join pg_statistic_ext_data on (oid = stxoid),
|
|||||||
to decide which combinations are compatible.
|
to decide which combinations are compatible.
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1 AND b = 10;
|
EXPLAIN (ANALYZE, TIMING OFF, BUFFERS OFF) SELECT * FROM t WHERE a = 1 AND b = 10;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------------&zwsp;--------
|
-------------------------------------------------------------------&zwsp;--------
|
||||||
Seq Scan on t (cost=0.00..195.00 rows=1 width=8) (actual rows=0 loops=1)
|
Seq Scan on t (cost=0.00..195.00 rows=1 width=8) (actual rows=0 loops=1)
|
||||||
@ -685,7 +685,7 @@ EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1 AND b = 10;
|
|||||||
consider the following range query for the same table:
|
consider the following range query for the same table:
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a <= 49 AND b > 49;
|
EXPLAIN (ANALYZE, TIMING OFF, BUFFERS OFF) SELECT * FROM t WHERE a <= 49 AND b > 49;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------------&zwsp;--------
|
-------------------------------------------------------------------&zwsp;--------
|
||||||
Seq Scan on t (cost=0.00..195.00 rows=1 width=8) (actual rows=0 loops=1)
|
Seq Scan on t (cost=0.00..195.00 rows=1 width=8) (actual rows=0 loops=1)
|
||||||
|
@ -201,8 +201,10 @@ ROLLBACK;
|
|||||||
query processing.
|
query processing.
|
||||||
The number of blocks shown for an
|
The number of blocks shown for an
|
||||||
upper-level node includes those used by all its child nodes. In text
|
upper-level node includes those used by all its child nodes. In text
|
||||||
format, only non-zero values are printed. This parameter defaults to
|
format, only non-zero values are printed. Buffers information is
|
||||||
<literal>FALSE</literal>.
|
included by default when <literal>ANALYZE</literal> is used but
|
||||||
|
otherwise is not included by default, but can be enabled using this
|
||||||
|
option.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -500,11 +502,13 @@ EXPLAIN ANALYZE EXECUTE query(100, 200);
|
|||||||
HashAggregate (cost=10.77..10.87 rows=10 width=12) (actual time=0.043..0.044 rows=10 loops=1)
|
HashAggregate (cost=10.77..10.87 rows=10 width=12) (actual time=0.043..0.044 rows=10 loops=1)
|
||||||
Group Key: foo
|
Group Key: foo
|
||||||
Batches: 1 Memory Usage: 24kB
|
Batches: 1 Memory Usage: 24kB
|
||||||
|
Buffers: shared hit=4
|
||||||
-> Index Scan using test_pkey on test (cost=0.29..10.27 rows=99 width=8) (actual time=0.009..0.025 rows=99 loops=1)
|
-> Index Scan using test_pkey on test (cost=0.29..10.27 rows=99 width=8) (actual time=0.009..0.025 rows=99 loops=1)
|
||||||
Index Cond: ((id > 100) AND (id < 200))
|
Index Cond: ((id > 100) AND (id < 200))
|
||||||
|
Buffers: shared hit=4
|
||||||
Planning Time: 0.244 ms
|
Planning Time: 0.244 ms
|
||||||
Execution Time: 0.073 ms
|
Execution Time: 0.073 ms
|
||||||
(7 rows)
|
(9 rows)
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
@ -198,6 +198,7 @@ ExplainQuery(ParseState *pstate, ExplainStmt *stmt,
|
|||||||
List *rewritten;
|
List *rewritten;
|
||||||
ListCell *lc;
|
ListCell *lc;
|
||||||
bool timing_set = false;
|
bool timing_set = false;
|
||||||
|
bool buffers_set = false;
|
||||||
bool summary_set = false;
|
bool summary_set = false;
|
||||||
|
|
||||||
/* Parse options list. */
|
/* Parse options list. */
|
||||||
@ -212,7 +213,10 @@ ExplainQuery(ParseState *pstate, ExplainStmt *stmt,
|
|||||||
else if (strcmp(opt->defname, "costs") == 0)
|
else if (strcmp(opt->defname, "costs") == 0)
|
||||||
es->costs = defGetBoolean(opt);
|
es->costs = defGetBoolean(opt);
|
||||||
else if (strcmp(opt->defname, "buffers") == 0)
|
else if (strcmp(opt->defname, "buffers") == 0)
|
||||||
|
{
|
||||||
|
buffers_set = true;
|
||||||
es->buffers = defGetBoolean(opt);
|
es->buffers = defGetBoolean(opt);
|
||||||
|
}
|
||||||
else if (strcmp(opt->defname, "wal") == 0)
|
else if (strcmp(opt->defname, "wal") == 0)
|
||||||
es->wal = defGetBoolean(opt);
|
es->wal = defGetBoolean(opt);
|
||||||
else if (strcmp(opt->defname, "settings") == 0)
|
else if (strcmp(opt->defname, "settings") == 0)
|
||||||
@ -292,6 +296,9 @@ ExplainQuery(ParseState *pstate, ExplainStmt *stmt,
|
|||||||
/* if the timing was not set explicitly, set default value */
|
/* if the timing was not set explicitly, set default value */
|
||||||
es->timing = (timing_set) ? es->timing : es->analyze;
|
es->timing = (timing_set) ? es->timing : es->analyze;
|
||||||
|
|
||||||
|
/* if the buffers was not set explicitly, set default value */
|
||||||
|
es->buffers = (buffers_set) ? es->buffers : es->analyze;
|
||||||
|
|
||||||
/* check that timing is used with EXPLAIN ANALYZE */
|
/* check that timing is used with EXPLAIN ANALYZE */
|
||||||
if (es->timing && !es->analyze)
|
if (es->timing && !es->analyze)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
|
@ -845,7 +845,7 @@ INSERT INTO brin_date_test SELECT '5874897-12-01'::date + i FROM generate_series
|
|||||||
CREATE INDEX ON brin_date_test USING brin (a date_minmax_multi_ops) WITH (pages_per_range=1);
|
CREATE INDEX ON brin_date_test USING brin (a date_minmax_multi_ops) WITH (pages_per_range=1);
|
||||||
SET enable_seqscan = off;
|
SET enable_seqscan = off;
|
||||||
-- make sure the ranges were built correctly and 2023-01-01 eliminates all
|
-- make sure the ranges were built correctly and 2023-01-01 eliminates all
|
||||||
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF)
|
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF, BUFFERS OFF)
|
||||||
SELECT * FROM brin_date_test WHERE a = '2023-01-01'::date;
|
SELECT * FROM brin_date_test WHERE a = '2023-01-01'::date;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
@ -864,7 +864,7 @@ INSERT INTO brin_timestamp_test
|
|||||||
SELECT i FROM generate_series('2000-01-01'::timestamp, '2000-02-09'::timestamp, '1 day'::interval) s(i);
|
SELECT i FROM generate_series('2000-01-01'::timestamp, '2000-02-09'::timestamp, '1 day'::interval) s(i);
|
||||||
CREATE INDEX ON brin_timestamp_test USING brin (a timestamp_minmax_multi_ops) WITH (pages_per_range=1);
|
CREATE INDEX ON brin_timestamp_test USING brin (a timestamp_minmax_multi_ops) WITH (pages_per_range=1);
|
||||||
SET enable_seqscan = off;
|
SET enable_seqscan = off;
|
||||||
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF)
|
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF, BUFFERS OFF)
|
||||||
SELECT * FROM brin_timestamp_test WHERE a = '2023-01-01'::timestamp;
|
SELECT * FROM brin_timestamp_test WHERE a = '2023-01-01'::timestamp;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
@ -874,7 +874,7 @@ SELECT * FROM brin_timestamp_test WHERE a = '2023-01-01'::timestamp;
|
|||||||
Index Cond: (a = '2023-01-01 00:00:00'::timestamp without time zone)
|
Index Cond: (a = '2023-01-01 00:00:00'::timestamp without time zone)
|
||||||
(4 rows)
|
(4 rows)
|
||||||
|
|
||||||
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF)
|
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF, BUFFERS OFF)
|
||||||
SELECT * FROM brin_timestamp_test WHERE a = '1900-01-01'::timestamp;
|
SELECT * FROM brin_timestamp_test WHERE a = '1900-01-01'::timestamp;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
@ -892,7 +892,7 @@ INSERT INTO brin_date_test VALUES ('-infinity'), ('infinity');
|
|||||||
INSERT INTO brin_date_test SELECT '2000-01-01'::date + i FROM generate_series(1, 40) s(i);
|
INSERT INTO brin_date_test SELECT '2000-01-01'::date + i FROM generate_series(1, 40) s(i);
|
||||||
CREATE INDEX ON brin_date_test USING brin (a date_minmax_multi_ops) WITH (pages_per_range=1);
|
CREATE INDEX ON brin_date_test USING brin (a date_minmax_multi_ops) WITH (pages_per_range=1);
|
||||||
SET enable_seqscan = off;
|
SET enable_seqscan = off;
|
||||||
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF)
|
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF, BUFFERS OFF)
|
||||||
SELECT * FROM brin_date_test WHERE a = '2023-01-01'::date;
|
SELECT * FROM brin_date_test WHERE a = '2023-01-01'::date;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
@ -902,7 +902,7 @@ SELECT * FROM brin_date_test WHERE a = '2023-01-01'::date;
|
|||||||
Index Cond: (a = '2023-01-01'::date)
|
Index Cond: (a = '2023-01-01'::date)
|
||||||
(4 rows)
|
(4 rows)
|
||||||
|
|
||||||
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF)
|
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF, BUFFERS OFF)
|
||||||
SELECT * FROM brin_date_test WHERE a = '1900-01-01'::date;
|
SELECT * FROM brin_date_test WHERE a = '1900-01-01'::date;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
@ -921,7 +921,7 @@ INSERT INTO brin_interval_test SELECT (i || ' years')::interval FROM generate_se
|
|||||||
INSERT INTO brin_interval_test SELECT (i || ' years')::interval FROM generate_series( 177999980, 178000000) s(i);
|
INSERT INTO brin_interval_test SELECT (i || ' years')::interval FROM generate_series( 177999980, 178000000) s(i);
|
||||||
CREATE INDEX ON brin_interval_test USING brin (a interval_minmax_multi_ops) WITH (pages_per_range=1);
|
CREATE INDEX ON brin_interval_test USING brin (a interval_minmax_multi_ops) WITH (pages_per_range=1);
|
||||||
SET enable_seqscan = off;
|
SET enable_seqscan = off;
|
||||||
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF)
|
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF, BUFFERS OFF)
|
||||||
SELECT * FROM brin_interval_test WHERE a = '-30 years'::interval;
|
SELECT * FROM brin_interval_test WHERE a = '-30 years'::interval;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
@ -931,7 +931,7 @@ SELECT * FROM brin_interval_test WHERE a = '-30 years'::interval;
|
|||||||
Index Cond: (a = '@ 30 years ago'::interval)
|
Index Cond: (a = '@ 30 years ago'::interval)
|
||||||
(4 rows)
|
(4 rows)
|
||||||
|
|
||||||
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF)
|
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF, BUFFERS OFF)
|
||||||
SELECT * FROM brin_interval_test WHERE a = '30 years'::interval;
|
SELECT * FROM brin_interval_test WHERE a = '30 years'::interval;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
@ -949,7 +949,7 @@ INSERT INTO brin_interval_test VALUES ('-infinity'), ('infinity');
|
|||||||
INSERT INTO brin_interval_test SELECT (i || ' days')::interval FROM generate_series(100, 140) s(i);
|
INSERT INTO brin_interval_test SELECT (i || ' days')::interval FROM generate_series(100, 140) s(i);
|
||||||
CREATE INDEX ON brin_interval_test USING brin (a interval_minmax_multi_ops) WITH (pages_per_range=1);
|
CREATE INDEX ON brin_interval_test USING brin (a interval_minmax_multi_ops) WITH (pages_per_range=1);
|
||||||
SET enable_seqscan = off;
|
SET enable_seqscan = off;
|
||||||
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF)
|
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF, BUFFERS OFF)
|
||||||
SELECT * FROM brin_interval_test WHERE a = '-30 years'::interval;
|
SELECT * FROM brin_interval_test WHERE a = '-30 years'::interval;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
@ -959,7 +959,7 @@ SELECT * FROM brin_interval_test WHERE a = '-30 years'::interval;
|
|||||||
Index Cond: (a = '@ 30 years ago'::interval)
|
Index Cond: (a = '@ 30 years ago'::interval)
|
||||||
(4 rows)
|
(4 rows)
|
||||||
|
|
||||||
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF)
|
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF, BUFFERS OFF)
|
||||||
SELECT * FROM brin_interval_test WHERE a = '30 years'::interval;
|
SELECT * FROM brin_interval_test WHERE a = '30 years'::interval;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
|
@ -60,7 +60,7 @@ select explain_filter('explain select * from int8_tbl i8');
|
|||||||
Seq Scan on int8_tbl i8 (cost=N.N..N.N rows=N width=N)
|
Seq Scan on int8_tbl i8 (cost=N.N..N.N rows=N width=N)
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
select explain_filter('explain (analyze) select * from int8_tbl i8');
|
select explain_filter('explain (analyze, buffers off) select * from int8_tbl i8');
|
||||||
explain_filter
|
explain_filter
|
||||||
-----------------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------------
|
||||||
Seq Scan on int8_tbl i8 (cost=N.N..N.N rows=N width=N) (actual time=N.N..N.N rows=N loops=N)
|
Seq Scan on int8_tbl i8 (cost=N.N..N.N rows=N width=N) (actual time=N.N..N.N rows=N loops=N)
|
||||||
@ -68,7 +68,7 @@ select explain_filter('explain (analyze) select * from int8_tbl i8');
|
|||||||
Execution Time: N.N ms
|
Execution Time: N.N ms
|
||||||
(3 rows)
|
(3 rows)
|
||||||
|
|
||||||
select explain_filter('explain (analyze, verbose) select * from int8_tbl i8');
|
select explain_filter('explain (analyze, buffers off, verbose) select * from int8_tbl i8');
|
||||||
explain_filter
|
explain_filter
|
||||||
------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------
|
||||||
Seq Scan on public.int8_tbl i8 (cost=N.N..N.N rows=N width=N) (actual time=N.N..N.N rows=N loops=N)
|
Seq Scan on public.int8_tbl i8 (cost=N.N..N.N rows=N width=N) (actual time=N.N..N.N rows=N loops=N)
|
||||||
@ -352,7 +352,7 @@ select explain_filter('explain (memory) select * from int8_tbl i8');
|
|||||||
Memory: used=NkB allocated=NkB
|
Memory: used=NkB allocated=NkB
|
||||||
(2 rows)
|
(2 rows)
|
||||||
|
|
||||||
select explain_filter('explain (memory, analyze) select * from int8_tbl i8');
|
select explain_filter('explain (memory, analyze, buffers off) select * from int8_tbl i8');
|
||||||
explain_filter
|
explain_filter
|
||||||
-----------------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------------
|
||||||
Seq Scan on int8_tbl i8 (cost=N.N..N.N rows=N width=N) (actual time=N.N..N.N rows=N loops=N)
|
Seq Scan on int8_tbl i8 (cost=N.N..N.N rows=N width=N) (actual time=N.N..N.N rows=N loops=N)
|
||||||
@ -400,9 +400,29 @@ select explain_filter('explain (memory, analyze, format json) select * from int8
|
|||||||
"Actual Total Time": N.N, +
|
"Actual Total Time": N.N, +
|
||||||
"Actual Rows": N, +
|
"Actual Rows": N, +
|
||||||
"Actual Loops": N, +
|
"Actual Loops": N, +
|
||||||
"Disabled": false +
|
"Disabled": false, +
|
||||||
|
"Shared Hit Blocks": N, +
|
||||||
|
"Shared Read Blocks": N, +
|
||||||
|
"Shared Dirtied Blocks": N, +
|
||||||
|
"Shared Written Blocks": N, +
|
||||||
|
"Local Hit Blocks": N, +
|
||||||
|
"Local Read Blocks": N, +
|
||||||
|
"Local Dirtied Blocks": N, +
|
||||||
|
"Local Written Blocks": N, +
|
||||||
|
"Temp Read Blocks": N, +
|
||||||
|
"Temp Written Blocks": N +
|
||||||
}, +
|
}, +
|
||||||
"Planning": { +
|
"Planning": { +
|
||||||
|
"Shared Hit Blocks": N, +
|
||||||
|
"Shared Read Blocks": N, +
|
||||||
|
"Shared Dirtied Blocks": N, +
|
||||||
|
"Shared Written Blocks": N, +
|
||||||
|
"Local Hit Blocks": N, +
|
||||||
|
"Local Read Blocks": N, +
|
||||||
|
"Local Dirtied Blocks": N, +
|
||||||
|
"Local Written Blocks": N, +
|
||||||
|
"Temp Read Blocks": N, +
|
||||||
|
"Temp Written Blocks": N, +
|
||||||
"Memory Used": N, +
|
"Memory Used": N, +
|
||||||
"Memory Allocated": N +
|
"Memory Allocated": N +
|
||||||
}, +
|
}, +
|
||||||
@ -680,7 +700,7 @@ select explain_filter('explain (verbose) create table test_ctas as select 1');
|
|||||||
(3 rows)
|
(3 rows)
|
||||||
|
|
||||||
-- Test SERIALIZE option
|
-- Test SERIALIZE option
|
||||||
select explain_filter('explain (analyze,serialize) select * from int8_tbl i8');
|
select explain_filter('explain (analyze,buffers off,serialize) select * from int8_tbl i8');
|
||||||
explain_filter
|
explain_filter
|
||||||
-----------------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------------
|
||||||
Seq Scan on int8_tbl i8 (cost=N.N..N.N rows=N width=N) (actual time=N.N..N.N rows=N loops=N)
|
Seq Scan on int8_tbl i8 (cost=N.N..N.N rows=N width=N) (actual time=N.N..N.N rows=N loops=N)
|
||||||
@ -708,7 +728,7 @@ select explain_filter('explain (analyze,serialize binary,buffers,timing) select
|
|||||||
(4 rows)
|
(4 rows)
|
||||||
|
|
||||||
-- this tests an edge case where we have no data to return
|
-- this tests an edge case where we have no data to return
|
||||||
select explain_filter('explain (analyze,serialize) create temp table explain_temp as select * from int8_tbl i8');
|
select explain_filter('explain (analyze,buffers off,serialize) create temp table explain_temp as select * from int8_tbl i8');
|
||||||
explain_filter
|
explain_filter
|
||||||
-----------------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------------
|
||||||
Seq Scan on int8_tbl i8 (cost=N.N..N.N rows=N width=N) (actual time=N.N..N.N rows=N loops=N)
|
Seq Scan on int8_tbl i8 (cost=N.N..N.N rows=N width=N) (actual time=N.N..N.N rows=N loops=N)
|
||||||
@ -718,7 +738,7 @@ select explain_filter('explain (analyze,serialize) create temp table explain_tem
|
|||||||
(4 rows)
|
(4 rows)
|
||||||
|
|
||||||
-- Test tuplestore storage usage in Window aggregate (memory case)
|
-- Test tuplestore storage usage in Window aggregate (memory case)
|
||||||
select explain_filter('explain (analyze,costs off) select sum(n) over() from generate_series(1,10) a(n)');
|
select explain_filter('explain (analyze,buffers off,costs off) select sum(n) over() from generate_series(1,10) a(n)');
|
||||||
explain_filter
|
explain_filter
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
WindowAgg (actual time=N.N..N.N rows=N loops=N)
|
WindowAgg (actual time=N.N..N.N rows=N loops=N)
|
||||||
@ -730,7 +750,7 @@ select explain_filter('explain (analyze,costs off) select sum(n) over() from gen
|
|||||||
|
|
||||||
-- Test tuplestore storage usage in Window aggregate (disk case)
|
-- Test tuplestore storage usage in Window aggregate (disk case)
|
||||||
set work_mem to 64;
|
set work_mem to 64;
|
||||||
select explain_filter('explain (analyze,costs off) select sum(n) over() from generate_series(1,2000) a(n)');
|
select explain_filter('explain (analyze,buffers off,costs off) select sum(n) over() from generate_series(1,2000) a(n)');
|
||||||
explain_filter
|
explain_filter
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
WindowAgg (actual time=N.N..N.N rows=N loops=N)
|
WindowAgg (actual time=N.N..N.N rows=N loops=N)
|
||||||
@ -741,7 +761,7 @@ select explain_filter('explain (analyze,costs off) select sum(n) over() from gen
|
|||||||
(5 rows)
|
(5 rows)
|
||||||
|
|
||||||
-- Test tuplestore storage usage in Window aggregate (memory and disk case, final result is disk)
|
-- Test tuplestore storage usage in Window aggregate (memory and disk case, final result is disk)
|
||||||
select explain_filter('explain (analyze,costs off) select sum(n) over(partition by m) from (SELECT n < 3 as m, n from generate_series(1,2000) a(n))');
|
select explain_filter('explain (analyze,buffers off,costs off) select sum(n) over(partition by m) from (SELECT n < 3 as m, n from generate_series(1,2000) a(n))');
|
||||||
explain_filter
|
explain_filter
|
||||||
--------------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------------
|
||||||
WindowAgg (actual time=N.N..N.N rows=N loops=N)
|
WindowAgg (actual time=N.N..N.N rows=N loops=N)
|
||||||
|
@ -39,7 +39,7 @@ declare
|
|||||||
line text;
|
line text;
|
||||||
begin
|
begin
|
||||||
for line in
|
for line in
|
||||||
execute 'explain (analyze, costs off, summary off, timing off) ' || query
|
execute 'explain (analyze, costs off, summary off, timing off, buffers off) ' || query
|
||||||
loop
|
loop
|
||||||
out_line := regexp_replace(line, '\d+kB', 'NNkB', 'g');
|
out_line := regexp_replace(line, '\d+kB', 'NNkB', 'g');
|
||||||
return next;
|
return next;
|
||||||
@ -55,7 +55,7 @@ declare
|
|||||||
element jsonb;
|
element jsonb;
|
||||||
matching_nodes jsonb := '[]'::jsonb;
|
matching_nodes jsonb := '[]'::jsonb;
|
||||||
begin
|
begin
|
||||||
execute 'explain (analyze, costs off, summary off, timing off, format ''json'') ' || query into strict elements;
|
execute 'explain (analyze, costs off, summary off, timing off, buffers off, format ''json'') ' || query into strict elements;
|
||||||
while jsonb_array_length(elements) > 0 loop
|
while jsonb_array_length(elements) > 0 loop
|
||||||
element := elements->0;
|
element := elements->0;
|
||||||
elements := elements - 0;
|
elements := elements - 0;
|
||||||
|
@ -10,7 +10,7 @@ declare
|
|||||||
ln text;
|
ln text;
|
||||||
begin
|
begin
|
||||||
for ln in
|
for ln in
|
||||||
execute format('explain (analyze, costs off, summary off, timing off) %s',
|
execute format('explain (analyze, costs off, summary off, timing off, buffers off) %s',
|
||||||
query)
|
query)
|
||||||
loop
|
loop
|
||||||
if hide_hitmiss = true then
|
if hide_hitmiss = true then
|
||||||
|
@ -1621,7 +1621,7 @@ $$
|
|||||||
DECLARE ln text;
|
DECLARE ln text;
|
||||||
BEGIN
|
BEGIN
|
||||||
FOR ln IN
|
FOR ln IN
|
||||||
EXECUTE 'explain (analyze, timing off, summary off, costs off) ' ||
|
EXECUTE 'explain (analyze, timing off, summary off, costs off, buffers off) ' ||
|
||||||
query
|
query
|
||||||
LOOP
|
LOOP
|
||||||
ln := regexp_replace(ln, '(Memory( Usage)?|Buckets|Batches): \S*', '\1: xxx', 'g');
|
ln := regexp_replace(ln, '(Memory( Usage)?|Buckets|Batches): \S*', '\1: xxx', 'g');
|
||||||
|
@ -11,7 +11,7 @@ declare
|
|||||||
ln text;
|
ln text;
|
||||||
begin
|
begin
|
||||||
for ln in
|
for ln in
|
||||||
execute format('explain (analyze, costs off, summary off, timing off) %s',
|
execute format('explain (analyze, costs off, summary off, timing off, buffers off) %s',
|
||||||
query)
|
query)
|
||||||
loop
|
loop
|
||||||
ln := regexp_replace(ln, 'Maximum Storage: \d+', 'Maximum Storage: N');
|
ln := regexp_replace(ln, 'Maximum Storage: \d+', 'Maximum Storage: N');
|
||||||
@ -2127,7 +2127,7 @@ create table ab_a3_b3 partition of ab_a3 for values in (3);
|
|||||||
set enable_indexonlyscan = off;
|
set enable_indexonlyscan = off;
|
||||||
prepare ab_q1 (int, int, int) as
|
prepare ab_q1 (int, int, int) as
|
||||||
select * from ab where a between $1 and $2 and b <= $3;
|
select * from ab where a between $1 and $2 and b <= $3;
|
||||||
explain (analyze, costs off, summary off, timing off) execute ab_q1 (2, 2, 3);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute ab_q1 (2, 2, 3);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
Append (actual rows=0 loops=1)
|
Append (actual rows=0 loops=1)
|
||||||
@ -2140,7 +2140,7 @@ explain (analyze, costs off, summary off, timing off) execute ab_q1 (2, 2, 3);
|
|||||||
Filter: ((a >= $1) AND (a <= $2) AND (b <= $3))
|
Filter: ((a >= $1) AND (a <= $2) AND (b <= $3))
|
||||||
(8 rows)
|
(8 rows)
|
||||||
|
|
||||||
explain (analyze, costs off, summary off, timing off) execute ab_q1 (1, 2, 3);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute ab_q1 (1, 2, 3);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
Append (actual rows=0 loops=1)
|
Append (actual rows=0 loops=1)
|
||||||
@ -2163,7 +2163,7 @@ deallocate ab_q1;
|
|||||||
-- Runtime pruning after optimizer pruning
|
-- Runtime pruning after optimizer pruning
|
||||||
prepare ab_q1 (int, int) as
|
prepare ab_q1 (int, int) as
|
||||||
select a from ab where a between $1 and $2 and b < 3;
|
select a from ab where a between $1 and $2 and b < 3;
|
||||||
explain (analyze, costs off, summary off, timing off) execute ab_q1 (2, 2);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute ab_q1 (2, 2);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
Append (actual rows=0 loops=1)
|
Append (actual rows=0 loops=1)
|
||||||
@ -2174,7 +2174,7 @@ explain (analyze, costs off, summary off, timing off) execute ab_q1 (2, 2);
|
|||||||
Filter: ((a >= $1) AND (a <= $2) AND (b < 3))
|
Filter: ((a >= $1) AND (a <= $2) AND (b < 3))
|
||||||
(6 rows)
|
(6 rows)
|
||||||
|
|
||||||
explain (analyze, costs off, summary off, timing off) execute ab_q1 (2, 4);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute ab_q1 (2, 4);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
Append (actual rows=0 loops=1)
|
Append (actual rows=0 loops=1)
|
||||||
@ -2193,7 +2193,7 @@ explain (analyze, costs off, summary off, timing off) execute ab_q1 (2, 4);
|
|||||||
-- different levels of partitioning.
|
-- different levels of partitioning.
|
||||||
prepare ab_q2 (int, int) as
|
prepare ab_q2 (int, int) as
|
||||||
select a from ab where a between $1 and $2 and b < (select 3);
|
select a from ab where a between $1 and $2 and b < (select 3);
|
||||||
explain (analyze, costs off, summary off, timing off) execute ab_q2 (2, 2);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute ab_q2 (2, 2);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
||||||
Append (actual rows=0 loops=1)
|
Append (actual rows=0 loops=1)
|
||||||
@ -2211,7 +2211,7 @@ explain (analyze, costs off, summary off, timing off) execute ab_q2 (2, 2);
|
|||||||
-- As above, but swap the PARAM_EXEC Param to the first partition level
|
-- As above, but swap the PARAM_EXEC Param to the first partition level
|
||||||
prepare ab_q3 (int, int) as
|
prepare ab_q3 (int, int) as
|
||||||
select a from ab where b between $1 and $2 and a < (select 3);
|
select a from ab where b between $1 and $2 and a < (select 3);
|
||||||
explain (analyze, costs off, summary off, timing off) execute ab_q3 (2, 2);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute ab_q3 (2, 2);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
||||||
Append (actual rows=0 loops=1)
|
Append (actual rows=0 loops=1)
|
||||||
@ -2273,7 +2273,7 @@ begin;
|
|||||||
-- Test run-time pruning using stable functions
|
-- Test run-time pruning using stable functions
|
||||||
create function list_part_fn(int) returns int as $$ begin return $1; end;$$ language plpgsql stable;
|
create function list_part_fn(int) returns int as $$ begin return $1; end;$$ language plpgsql stable;
|
||||||
-- Ensure pruning works using a stable function containing no Vars
|
-- Ensure pruning works using a stable function containing no Vars
|
||||||
explain (analyze, costs off, summary off, timing off) select * from list_part where a = list_part_fn(1);
|
explain (analyze, costs off, summary off, timing off, buffers off) select * from list_part where a = list_part_fn(1);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
------------------------------------------------------------------
|
------------------------------------------------------------------
|
||||||
Append (actual rows=1 loops=1)
|
Append (actual rows=1 loops=1)
|
||||||
@ -2283,7 +2283,7 @@ explain (analyze, costs off, summary off, timing off) select * from list_part wh
|
|||||||
(4 rows)
|
(4 rows)
|
||||||
|
|
||||||
-- Ensure pruning does not take place when the function has a Var parameter
|
-- Ensure pruning does not take place when the function has a Var parameter
|
||||||
explain (analyze, costs off, summary off, timing off) select * from list_part where a = list_part_fn(a);
|
explain (analyze, costs off, summary off, timing off, buffers off) select * from list_part where a = list_part_fn(a);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
------------------------------------------------------------------
|
------------------------------------------------------------------
|
||||||
Append (actual rows=4 loops=1)
|
Append (actual rows=4 loops=1)
|
||||||
@ -2298,7 +2298,7 @@ explain (analyze, costs off, summary off, timing off) select * from list_part wh
|
|||||||
(9 rows)
|
(9 rows)
|
||||||
|
|
||||||
-- Ensure pruning does not take place when the expression contains a Var.
|
-- Ensure pruning does not take place when the expression contains a Var.
|
||||||
explain (analyze, costs off, summary off, timing off) select * from list_part where a = list_part_fn(1) + a;
|
explain (analyze, costs off, summary off, timing off, buffers off) select * from list_part where a = list_part_fn(1) + a;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
------------------------------------------------------------------
|
------------------------------------------------------------------
|
||||||
Append (actual rows=0 loops=1)
|
Append (actual rows=0 loops=1)
|
||||||
@ -2334,7 +2334,7 @@ declare
|
|||||||
ln text;
|
ln text;
|
||||||
begin
|
begin
|
||||||
for ln in
|
for ln in
|
||||||
execute format('explain (analyze, costs off, summary off, timing off) %s',
|
execute format('explain (analyze, costs off, summary off, timing off, buffers off) %s',
|
||||||
$1)
|
$1)
|
||||||
loop
|
loop
|
||||||
ln := regexp_replace(ln, 'Workers Launched: \d+', 'Workers Launched: N');
|
ln := regexp_replace(ln, 'Workers Launched: \d+', 'Workers Launched: N');
|
||||||
@ -2641,7 +2641,7 @@ reset parallel_tuple_cost;
|
|||||||
reset min_parallel_table_scan_size;
|
reset min_parallel_table_scan_size;
|
||||||
reset max_parallel_workers_per_gather;
|
reset max_parallel_workers_per_gather;
|
||||||
-- Test run-time partition pruning with an initplan
|
-- Test run-time partition pruning with an initplan
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from ab where a = (select max(a) from lprt_a) and b = (select max(a)-1 from lprt_a);
|
select * from ab where a = (select max(a) from lprt_a) and b = (select max(a)-1 from lprt_a);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
@ -2700,7 +2700,7 @@ select * from ab where a = (select max(a) from lprt_a) and b = (select max(a)-1
|
|||||||
(52 rows)
|
(52 rows)
|
||||||
|
|
||||||
-- Test run-time partition pruning with UNION ALL parents
|
-- Test run-time partition pruning with UNION ALL parents
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from (select * from ab where a = 1 union all select * from ab) ab where b = (select 1);
|
select * from (select * from ab where a = 1 union all select * from ab) ab where b = (select 1);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@ -2744,7 +2744,7 @@ select * from (select * from ab where a = 1 union all select * from ab) ab where
|
|||||||
(37 rows)
|
(37 rows)
|
||||||
|
|
||||||
-- A case containing a UNION ALL with a non-partitioned child.
|
-- A case containing a UNION ALL with a non-partitioned child.
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from (select * from ab where a = 1 union all (values(10,5)) union all select * from ab) ab where b = (select 1);
|
select * from (select * from ab where a = 1 union all (values(10,5)) union all select * from ab) ab where b = (select 1);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@ -2803,7 +2803,7 @@ union all
|
|||||||
select tableoid::regclass,a,b from ab
|
select tableoid::regclass,a,b from ab
|
||||||
) ab where a = $1 and b = (select -10);
|
) ab where a = $1 and b = (select -10);
|
||||||
-- Ensure the xy_1 subplan is not pruned.
|
-- Ensure the xy_1 subplan is not pruned.
|
||||||
explain (analyze, costs off, summary off, timing off) execute ab_q6(1);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute ab_q6(1);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
--------------------------------------------------------
|
--------------------------------------------------------
|
||||||
Append (actual rows=0 loops=1)
|
Append (actual rows=0 loops=1)
|
||||||
@ -2952,7 +2952,7 @@ create index tprt6_idx on tprt_6 (col1);
|
|||||||
insert into tprt values (10), (20), (501), (502), (505), (1001), (4500);
|
insert into tprt values (10), (20), (501), (502), (505), (1001), (4500);
|
||||||
set enable_hashjoin = off;
|
set enable_hashjoin = off;
|
||||||
set enable_mergejoin = off;
|
set enable_mergejoin = off;
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from tbl1 join tprt on tbl1.col1 > tprt.col1;
|
select * from tbl1 join tprt on tbl1.col1 > tprt.col1;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
@ -2973,7 +2973,7 @@ select * from tbl1 join tprt on tbl1.col1 > tprt.col1;
|
|||||||
Index Cond: (col1 < tbl1.col1)
|
Index Cond: (col1 < tbl1.col1)
|
||||||
(15 rows)
|
(15 rows)
|
||||||
|
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from tbl1 join tprt on tbl1.col1 = tprt.col1;
|
select * from tbl1 join tprt on tbl1.col1 = tprt.col1;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
@ -3018,7 +3018,7 @@ order by tbl1.col1, tprt.col1;
|
|||||||
|
|
||||||
-- Multiple partitions
|
-- Multiple partitions
|
||||||
insert into tbl1 values (1001), (1010), (1011);
|
insert into tbl1 values (1001), (1010), (1011);
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from tbl1 inner join tprt on tbl1.col1 > tprt.col1;
|
select * from tbl1 inner join tprt on tbl1.col1 > tprt.col1;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
@ -3039,7 +3039,7 @@ select * from tbl1 inner join tprt on tbl1.col1 > tprt.col1;
|
|||||||
Index Cond: (col1 < tbl1.col1)
|
Index Cond: (col1 < tbl1.col1)
|
||||||
(15 rows)
|
(15 rows)
|
||||||
|
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from tbl1 inner join tprt on tbl1.col1 = tprt.col1;
|
select * from tbl1 inner join tprt on tbl1.col1 = tprt.col1;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
@ -3103,7 +3103,7 @@ order by tbl1.col1, tprt.col1;
|
|||||||
-- Last partition
|
-- Last partition
|
||||||
delete from tbl1;
|
delete from tbl1;
|
||||||
insert into tbl1 values (4400);
|
insert into tbl1 values (4400);
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from tbl1 join tprt on tbl1.col1 < tprt.col1;
|
select * from tbl1 join tprt on tbl1.col1 < tprt.col1;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
@ -3135,7 +3135,7 @@ order by tbl1.col1, tprt.col1;
|
|||||||
-- No matching partition
|
-- No matching partition
|
||||||
delete from tbl1;
|
delete from tbl1;
|
||||||
insert into tbl1 values (10000);
|
insert into tbl1 values (10000);
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from tbl1 join tprt on tbl1.col1 = tprt.col1;
|
select * from tbl1 join tprt on tbl1.col1 = tprt.col1;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
@ -3175,7 +3175,7 @@ alter table part_cab attach partition part_abc_p1 for values in(3);
|
|||||||
prepare part_abc_q1 (int, int, int) as
|
prepare part_abc_q1 (int, int, int) as
|
||||||
select * from part_abc where a = $1 and b = $2 and c = $3;
|
select * from part_abc where a = $1 and b = $2 and c = $3;
|
||||||
-- Single partition should be scanned.
|
-- Single partition should be scanned.
|
||||||
explain (analyze, costs off, summary off, timing off) execute part_abc_q1 (1, 2, 3);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute part_abc_q1 (1, 2, 3);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
----------------------------------------------------------
|
----------------------------------------------------------
|
||||||
Seq Scan on part_abc_p1 part_abc (actual rows=0 loops=1)
|
Seq Scan on part_abc_p1 part_abc (actual rows=0 loops=1)
|
||||||
@ -3200,7 +3200,7 @@ select * from listp where b = 1;
|
|||||||
-- partitions before finally detecting the correct set of 2nd level partitions
|
-- partitions before finally detecting the correct set of 2nd level partitions
|
||||||
-- which match the given parameter.
|
-- which match the given parameter.
|
||||||
prepare q1 (int,int) as select * from listp where b in ($1,$2);
|
prepare q1 (int,int) as select * from listp where b in ($1,$2);
|
||||||
explain (analyze, costs off, summary off, timing off) execute q1 (1,1);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute q1 (1,1);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------
|
-------------------------------------------------------------
|
||||||
Append (actual rows=0 loops=1)
|
Append (actual rows=0 loops=1)
|
||||||
@ -3209,7 +3209,7 @@ explain (analyze, costs off, summary off, timing off) execute q1 (1,1);
|
|||||||
Filter: (b = ANY (ARRAY[$1, $2]))
|
Filter: (b = ANY (ARRAY[$1, $2]))
|
||||||
(4 rows)
|
(4 rows)
|
||||||
|
|
||||||
explain (analyze, costs off, summary off, timing off) execute q1 (2,2);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute q1 (2,2);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------
|
-------------------------------------------------------------
|
||||||
Append (actual rows=0 loops=1)
|
Append (actual rows=0 loops=1)
|
||||||
@ -3219,7 +3219,7 @@ explain (analyze, costs off, summary off, timing off) execute q1 (2,2);
|
|||||||
(4 rows)
|
(4 rows)
|
||||||
|
|
||||||
-- Try with no matching partitions.
|
-- Try with no matching partitions.
|
||||||
explain (analyze, costs off, summary off, timing off) execute q1 (0,0);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute q1 (0,0);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
--------------------------------
|
--------------------------------
|
||||||
Append (actual rows=0 loops=1)
|
Append (actual rows=0 loops=1)
|
||||||
@ -3230,7 +3230,7 @@ deallocate q1;
|
|||||||
-- Test more complex cases where a not-equal condition further eliminates partitions.
|
-- Test more complex cases where a not-equal condition further eliminates partitions.
|
||||||
prepare q1 (int,int,int,int) as select * from listp where b in($1,$2) and $3 <> b and $4 <> b;
|
prepare q1 (int,int,int,int) as select * from listp where b in($1,$2) and $3 <> b and $4 <> b;
|
||||||
-- Both partitions allowed by IN clause, but one disallowed by <> clause
|
-- Both partitions allowed by IN clause, but one disallowed by <> clause
|
||||||
explain (analyze, costs off, summary off, timing off) execute q1 (1,2,2,0);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute q1 (1,2,2,0);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
Append (actual rows=0 loops=1)
|
Append (actual rows=0 loops=1)
|
||||||
@ -3240,7 +3240,7 @@ explain (analyze, costs off, summary off, timing off) execute q1 (1,2,2,0);
|
|||||||
(4 rows)
|
(4 rows)
|
||||||
|
|
||||||
-- Both partitions allowed by IN clause, then both excluded again by <> clauses.
|
-- Both partitions allowed by IN clause, then both excluded again by <> clauses.
|
||||||
explain (analyze, costs off, summary off, timing off) execute q1 (1,2,2,1);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute q1 (1,2,2,1);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
--------------------------------
|
--------------------------------
|
||||||
Append (actual rows=0 loops=1)
|
Append (actual rows=0 loops=1)
|
||||||
@ -3248,7 +3248,7 @@ explain (analyze, costs off, summary off, timing off) execute q1 (1,2,2,1);
|
|||||||
(2 rows)
|
(2 rows)
|
||||||
|
|
||||||
-- Ensure Params that evaluate to NULL properly prune away all partitions
|
-- Ensure Params that evaluate to NULL properly prune away all partitions
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from listp where a = (select null::int);
|
select * from listp where a = (select null::int);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
------------------------------------------------------
|
------------------------------------------------------
|
||||||
@ -3273,7 +3273,7 @@ create table stable_qual_pruning2 partition of stable_qual_pruning
|
|||||||
create table stable_qual_pruning3 partition of stable_qual_pruning
|
create table stable_qual_pruning3 partition of stable_qual_pruning
|
||||||
for values from ('3000-02-01') to ('3000-03-01');
|
for values from ('3000-02-01') to ('3000-03-01');
|
||||||
-- comparison against a stable value requires run-time pruning
|
-- comparison against a stable value requires run-time pruning
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from stable_qual_pruning where a < localtimestamp;
|
select * from stable_qual_pruning where a < localtimestamp;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
--------------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------------
|
||||||
@ -3286,7 +3286,7 @@ select * from stable_qual_pruning where a < localtimestamp;
|
|||||||
(6 rows)
|
(6 rows)
|
||||||
|
|
||||||
-- timestamp < timestamptz comparison is only stable, not immutable
|
-- timestamp < timestamptz comparison is only stable, not immutable
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from stable_qual_pruning where a < '2000-02-01'::timestamptz;
|
select * from stable_qual_pruning where a < '2000-02-01'::timestamptz;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
--------------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------------
|
||||||
@ -3297,7 +3297,7 @@ select * from stable_qual_pruning where a < '2000-02-01'::timestamptz;
|
|||||||
(4 rows)
|
(4 rows)
|
||||||
|
|
||||||
-- check ScalarArrayOp cases
|
-- check ScalarArrayOp cases
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from stable_qual_pruning
|
select * from stable_qual_pruning
|
||||||
where a = any(array['2010-02-01', '2020-01-01']::timestamp[]);
|
where a = any(array['2010-02-01', '2020-01-01']::timestamp[]);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
@ -3306,7 +3306,7 @@ select * from stable_qual_pruning
|
|||||||
One-Time Filter: false
|
One-Time Filter: false
|
||||||
(2 rows)
|
(2 rows)
|
||||||
|
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from stable_qual_pruning
|
select * from stable_qual_pruning
|
||||||
where a = any(array['2000-02-01', '2010-01-01']::timestamp[]);
|
where a = any(array['2000-02-01', '2010-01-01']::timestamp[]);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
@ -3315,7 +3315,7 @@ select * from stable_qual_pruning
|
|||||||
Filter: (a = ANY ('{"Tue Feb 01 00:00:00 2000","Fri Jan 01 00:00:00 2010"}'::timestamp without time zone[]))
|
Filter: (a = ANY ('{"Tue Feb 01 00:00:00 2000","Fri Jan 01 00:00:00 2010"}'::timestamp without time zone[]))
|
||||||
(2 rows)
|
(2 rows)
|
||||||
|
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from stable_qual_pruning
|
select * from stable_qual_pruning
|
||||||
where a = any(array['2000-02-01', localtimestamp]::timestamp[]);
|
where a = any(array['2000-02-01', localtimestamp]::timestamp[]);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
@ -3326,7 +3326,7 @@ select * from stable_qual_pruning
|
|||||||
Filter: (a = ANY (ARRAY['Tue Feb 01 00:00:00 2000'::timestamp without time zone, LOCALTIMESTAMP]))
|
Filter: (a = ANY (ARRAY['Tue Feb 01 00:00:00 2000'::timestamp without time zone, LOCALTIMESTAMP]))
|
||||||
(4 rows)
|
(4 rows)
|
||||||
|
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from stable_qual_pruning
|
select * from stable_qual_pruning
|
||||||
where a = any(array['2010-02-01', '2020-01-01']::timestamptz[]);
|
where a = any(array['2010-02-01', '2020-01-01']::timestamptz[]);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
@ -3335,7 +3335,7 @@ select * from stable_qual_pruning
|
|||||||
Subplans Removed: 3
|
Subplans Removed: 3
|
||||||
(2 rows)
|
(2 rows)
|
||||||
|
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from stable_qual_pruning
|
select * from stable_qual_pruning
|
||||||
where a = any(array['2000-02-01', '2010-01-01']::timestamptz[]);
|
where a = any(array['2000-02-01', '2010-01-01']::timestamptz[]);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
@ -3346,7 +3346,7 @@ select * from stable_qual_pruning
|
|||||||
Filter: (a = ANY ('{"Tue Feb 01 00:00:00 2000 PST","Fri Jan 01 00:00:00 2010 PST"}'::timestamp with time zone[]))
|
Filter: (a = ANY ('{"Tue Feb 01 00:00:00 2000 PST","Fri Jan 01 00:00:00 2010 PST"}'::timestamp with time zone[]))
|
||||||
(4 rows)
|
(4 rows)
|
||||||
|
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from stable_qual_pruning
|
select * from stable_qual_pruning
|
||||||
where a = any(null::timestamptz[]);
|
where a = any(null::timestamptz[]);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
@ -3374,7 +3374,7 @@ create table mc3p1 partition of mc3p
|
|||||||
create table mc3p2 partition of mc3p
|
create table mc3p2 partition of mc3p
|
||||||
for values from (2, minvalue, minvalue) to (3, maxvalue, maxvalue);
|
for values from (2, minvalue, minvalue) to (3, maxvalue, maxvalue);
|
||||||
insert into mc3p values (0, 1, 1), (1, 1, 1), (2, 1, 1);
|
insert into mc3p values (0, 1, 1), (1, 1, 1), (2, 1, 1);
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from mc3p where a < 3 and abs(b) = 1;
|
select * from mc3p where a < 3 and abs(b) = 1;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
--------------------------------------------------------
|
--------------------------------------------------------
|
||||||
@ -3394,7 +3394,7 @@ select * from mc3p where a < 3 and abs(b) = 1;
|
|||||||
--
|
--
|
||||||
prepare ps1 as
|
prepare ps1 as
|
||||||
select * from mc3p where a = $1 and abs(b) < (select 3);
|
select * from mc3p where a = $1 and abs(b) < (select 3);
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
execute ps1(1);
|
execute ps1(1);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------
|
-------------------------------------------------------------
|
||||||
@ -3409,7 +3409,7 @@ execute ps1(1);
|
|||||||
deallocate ps1;
|
deallocate ps1;
|
||||||
prepare ps2 as
|
prepare ps2 as
|
||||||
select * from mc3p where a <= $1 and abs(b) < (select 3);
|
select * from mc3p where a <= $1 and abs(b) < (select 3);
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
execute ps2(1);
|
execute ps2(1);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
--------------------------------------------------------------
|
--------------------------------------------------------------
|
||||||
@ -3431,7 +3431,7 @@ insert into boolvalues values('t'),('f');
|
|||||||
create table boolp (a bool) partition by list (a);
|
create table boolp (a bool) partition by list (a);
|
||||||
create table boolp_t partition of boolp for values in('t');
|
create table boolp_t partition of boolp for values in('t');
|
||||||
create table boolp_f partition of boolp for values in('f');
|
create table boolp_f partition of boolp for values in('f');
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from boolp where a = (select value from boolvalues where value);
|
select * from boolp where a = (select value from boolvalues where value);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-----------------------------------------------------------
|
-----------------------------------------------------------
|
||||||
@ -3446,7 +3446,7 @@ select * from boolp where a = (select value from boolvalues where value);
|
|||||||
Filter: (a = (InitPlan 1).col1)
|
Filter: (a = (InitPlan 1).col1)
|
||||||
(9 rows)
|
(9 rows)
|
||||||
|
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from boolp where a = (select value from boolvalues where not value);
|
select * from boolp where a = (select value from boolvalues where not value);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-----------------------------------------------------------
|
-----------------------------------------------------------
|
||||||
@ -3475,7 +3475,7 @@ insert into ma_test select x,x from generate_series(0,29) t(x);
|
|||||||
create index on ma_test (b);
|
create index on ma_test (b);
|
||||||
analyze ma_test;
|
analyze ma_test;
|
||||||
prepare mt_q1 (int) as select a from ma_test where a >= $1 and a % 10 = 5 order by b;
|
prepare mt_q1 (int) as select a from ma_test where a >= $1 and a % 10 = 5 order by b;
|
||||||
explain (analyze, costs off, summary off, timing off) execute mt_q1(15);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute mt_q1(15);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-----------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------
|
||||||
Merge Append (actual rows=2 loops=1)
|
Merge Append (actual rows=2 loops=1)
|
||||||
@ -3496,7 +3496,7 @@ execute mt_q1(15);
|
|||||||
25
|
25
|
||||||
(2 rows)
|
(2 rows)
|
||||||
|
|
||||||
explain (analyze, costs off, summary off, timing off) execute mt_q1(25);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute mt_q1(25);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-----------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------
|
||||||
Merge Append (actual rows=1 loops=1)
|
Merge Append (actual rows=1 loops=1)
|
||||||
@ -3514,7 +3514,7 @@ execute mt_q1(25);
|
|||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- Ensure MergeAppend behaves correctly when no subplans match
|
-- Ensure MergeAppend behaves correctly when no subplans match
|
||||||
explain (analyze, costs off, summary off, timing off) execute mt_q1(35);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute mt_q1(35);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
Merge Append (actual rows=0 loops=1)
|
Merge Append (actual rows=0 loops=1)
|
||||||
@ -3530,7 +3530,7 @@ execute mt_q1(35);
|
|||||||
deallocate mt_q1;
|
deallocate mt_q1;
|
||||||
prepare mt_q2 (int) as select * from ma_test where a >= $1 order by b limit 1;
|
prepare mt_q2 (int) as select * from ma_test where a >= $1 order by b limit 1;
|
||||||
-- Ensure output list looks sane when the MergeAppend has no subplans.
|
-- Ensure output list looks sane when the MergeAppend has no subplans.
|
||||||
explain (analyze, verbose, costs off, summary off, timing off) execute mt_q2 (35);
|
explain (analyze, verbose, costs off, summary off, timing off, buffers off) execute mt_q2 (35);
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
--------------------------------------------
|
--------------------------------------------
|
||||||
Limit (actual rows=0 loops=1)
|
Limit (actual rows=0 loops=1)
|
||||||
@ -3542,7 +3542,7 @@ explain (analyze, verbose, costs off, summary off, timing off) execute mt_q2 (35
|
|||||||
|
|
||||||
deallocate mt_q2;
|
deallocate mt_q2;
|
||||||
-- ensure initplan params properly prune partitions
|
-- ensure initplan params properly prune partitions
|
||||||
explain (analyze, costs off, summary off, timing off) select * from ma_test where a >= (select min(b) from ma_test_p2) order by b;
|
explain (analyze, costs off, summary off, timing off, buffers off) select * from ma_test where a >= (select min(b) from ma_test_p2) order by b;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-----------------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------------
|
||||||
Merge Append (actual rows=20 loops=1)
|
Merge Append (actual rows=20 loops=1)
|
||||||
@ -3992,7 +3992,7 @@ create table listp (a int, b int) partition by list (a);
|
|||||||
create table listp1 partition of listp for values in(1);
|
create table listp1 partition of listp for values in(1);
|
||||||
create table listp2 partition of listp for values in(2) partition by list(b);
|
create table listp2 partition of listp for values in(2) partition by list(b);
|
||||||
create table listp2_10 partition of listp2 for values in (10);
|
create table listp2_10 partition of listp2 for values in (10);
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from listp where a = (select 2) and b <> 10;
|
select * from listp where a = (select 2) and b <> 10;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
---------------------------------------------------
|
---------------------------------------------------
|
||||||
@ -4117,7 +4117,7 @@ create table rangep_0_to_100_3 partition of rangep_0_to_100 for values in(3);
|
|||||||
create table rangep_100_to_200 partition of rangep for values from (100) to (200);
|
create table rangep_100_to_200 partition of rangep for values from (100) to (200);
|
||||||
create index on rangep (a);
|
create index on rangep (a);
|
||||||
-- Ensure run-time pruning works on the nested Merge Append
|
-- Ensure run-time pruning works on the nested Merge Append
|
||||||
explain (analyze on, costs off, timing off, summary off)
|
explain (analyze on, costs off, timing off, summary off, buffers off)
|
||||||
select * from rangep where b IN((select 1),(select 2)) order by a;
|
select * from rangep where b IN((select 1),(select 2)) order by a;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -757,7 +757,7 @@ select * from onek2 where unique2 = 11 and stringu1 = 'ATAAAA';
|
|||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- actually run the query with an analyze to use the partial index
|
-- actually run the query with an analyze to use the partial index
|
||||||
explain (costs off, analyze on, timing off, summary off)
|
explain (costs off, analyze on, timing off, summary off, buffers off)
|
||||||
select * from onek2 where unique2 = 11 and stringu1 = 'ATAAAA';
|
select * from onek2 where unique2 = 11 and stringu1 = 'ATAAAA';
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-----------------------------------------------------------------
|
-----------------------------------------------------------------
|
||||||
|
@ -25,7 +25,7 @@ CREATE TABLE selinto_schema.tbl_withdata1 (a)
|
|||||||
AS SELECT generate_series(1,3) WITH DATA;
|
AS SELECT generate_series(1,3) WITH DATA;
|
||||||
INSERT INTO selinto_schema.tbl_withdata1 VALUES (4);
|
INSERT INTO selinto_schema.tbl_withdata1 VALUES (4);
|
||||||
ERROR: permission denied for table tbl_withdata1
|
ERROR: permission denied for table tbl_withdata1
|
||||||
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF)
|
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF, BUFFERS OFF)
|
||||||
CREATE TABLE selinto_schema.tbl_withdata2 (a) AS
|
CREATE TABLE selinto_schema.tbl_withdata2 (a) AS
|
||||||
SELECT generate_series(1,3) WITH DATA;
|
SELECT generate_series(1,3) WITH DATA;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
@ -62,7 +62,7 @@ EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF)
|
|||||||
-- EXECUTE and WITH NO DATA, passes.
|
-- EXECUTE and WITH NO DATA, passes.
|
||||||
CREATE TABLE selinto_schema.tbl_nodata3 (a) AS
|
CREATE TABLE selinto_schema.tbl_nodata3 (a) AS
|
||||||
EXECUTE data_sel WITH NO DATA;
|
EXECUTE data_sel WITH NO DATA;
|
||||||
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF)
|
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF, BUFFERS OFF)
|
||||||
CREATE TABLE selinto_schema.tbl_nodata4 (a) AS
|
CREATE TABLE selinto_schema.tbl_nodata4 (a) AS
|
||||||
EXECUTE data_sel WITH NO DATA;
|
EXECUTE data_sel WITH NO DATA;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
|
@ -580,7 +580,7 @@ select count(*) from bmscantest where a>1;
|
|||||||
-- test accumulation of stats for parallel nodes
|
-- test accumulation of stats for parallel nodes
|
||||||
reset enable_seqscan;
|
reset enable_seqscan;
|
||||||
alter table tenk2 set (parallel_workers = 0);
|
alter table tenk2 set (parallel_workers = 0);
|
||||||
explain (analyze, timing off, summary off, costs off)
|
explain (analyze, timing off, summary off, costs off, buffers off)
|
||||||
select count(*) from tenk1, tenk2 where tenk1.hundred > 1
|
select count(*) from tenk1, tenk2 where tenk1.hundred > 1
|
||||||
and tenk2.thousand=0;
|
and tenk2.thousand=0;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
@ -606,7 +606,7 @@ $$
|
|||||||
declare ln text;
|
declare ln text;
|
||||||
begin
|
begin
|
||||||
for ln in
|
for ln in
|
||||||
explain (analyze, timing off, summary off, costs off)
|
explain (analyze, timing off, summary off, costs off, buffers off)
|
||||||
select * from
|
select * from
|
||||||
(select ten from tenk1 where ten < 100 order by ten) ss
|
(select ten from tenk1 where ten < 100 order by ten) ss
|
||||||
right join (values (1),(2),(3)) v(x) on true
|
right join (values (1),(2),(3)) v(x) on true
|
||||||
@ -1169,7 +1169,7 @@ explain (costs off)
|
|||||||
-- to increase the parallel query test coverage
|
-- to increase the parallel query test coverage
|
||||||
SAVEPOINT settings;
|
SAVEPOINT settings;
|
||||||
SET LOCAL debug_parallel_query = 1;
|
SET LOCAL debug_parallel_query = 1;
|
||||||
EXPLAIN (analyze, timing off, summary off, costs off) SELECT * FROM tenk1;
|
EXPLAIN (analyze, timing off, summary off, costs off, buffers off) SELECT * FROM tenk1;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------
|
-------------------------------------------------------------
|
||||||
Gather (actual rows=10000 loops=1)
|
Gather (actual rows=10000 loops=1)
|
||||||
|
@ -1675,7 +1675,7 @@ $$
|
|||||||
declare ln text;
|
declare ln text;
|
||||||
begin
|
begin
|
||||||
for ln in
|
for ln in
|
||||||
explain (analyze, summary off, timing off, costs off)
|
explain (analyze, summary off, timing off, costs off, buffers off)
|
||||||
select * from (select pk,c2 from sq_limit order by c1,pk) as x limit 3
|
select * from (select pk,c2 from sq_limit order by c1,pk) as x limit 3
|
||||||
loop
|
loop
|
||||||
ln := regexp_replace(ln, 'Memory: \S*', 'Memory: xxx');
|
ln := regexp_replace(ln, 'Memory: \S*', 'Memory: xxx');
|
||||||
|
@ -189,7 +189,7 @@ FETCH NEXT FROM c;
|
|||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- perform update
|
-- perform update
|
||||||
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF)
|
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF, BUFFERS OFF)
|
||||||
UPDATE tidscan SET id = -id WHERE CURRENT OF c RETURNING *;
|
UPDATE tidscan SET id = -id WHERE CURRENT OF c RETURNING *;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
---------------------------------------------------
|
---------------------------------------------------
|
||||||
@ -205,7 +205,7 @@ FETCH NEXT FROM c;
|
|||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- perform update
|
-- perform update
|
||||||
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF)
|
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF, BUFFERS OFF)
|
||||||
UPDATE tidscan SET id = -id WHERE CURRENT OF c RETURNING *;
|
UPDATE tidscan SET id = -id WHERE CURRENT OF c RETURNING *;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
---------------------------------------------------
|
---------------------------------------------------
|
||||||
@ -229,7 +229,7 @@ FETCH NEXT FROM c;
|
|||||||
(0 rows)
|
(0 rows)
|
||||||
|
|
||||||
-- should error out
|
-- should error out
|
||||||
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF)
|
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF, BUFFERS OFF)
|
||||||
UPDATE tidscan SET id = -id WHERE CURRENT OF c RETURNING *;
|
UPDATE tidscan SET id = -id WHERE CURRENT OF c RETURNING *;
|
||||||
ERROR: cursor "c" is not positioned on a row
|
ERROR: cursor "c" is not positioned on a row
|
||||||
ROLLBACK;
|
ROLLBACK;
|
||||||
|
@ -619,7 +619,7 @@ CREATE INDEX ON brin_date_test USING brin (a date_minmax_multi_ops) WITH (pages_
|
|||||||
SET enable_seqscan = off;
|
SET enable_seqscan = off;
|
||||||
|
|
||||||
-- make sure the ranges were built correctly and 2023-01-01 eliminates all
|
-- make sure the ranges were built correctly and 2023-01-01 eliminates all
|
||||||
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF)
|
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF, BUFFERS OFF)
|
||||||
SELECT * FROM brin_date_test WHERE a = '2023-01-01'::date;
|
SELECT * FROM brin_date_test WHERE a = '2023-01-01'::date;
|
||||||
|
|
||||||
DROP TABLE brin_date_test;
|
DROP TABLE brin_date_test;
|
||||||
@ -636,10 +636,10 @@ CREATE INDEX ON brin_timestamp_test USING brin (a timestamp_minmax_multi_ops) WI
|
|||||||
|
|
||||||
SET enable_seqscan = off;
|
SET enable_seqscan = off;
|
||||||
|
|
||||||
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF)
|
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF, BUFFERS OFF)
|
||||||
SELECT * FROM brin_timestamp_test WHERE a = '2023-01-01'::timestamp;
|
SELECT * FROM brin_timestamp_test WHERE a = '2023-01-01'::timestamp;
|
||||||
|
|
||||||
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF)
|
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF, BUFFERS OFF)
|
||||||
SELECT * FROM brin_timestamp_test WHERE a = '1900-01-01'::timestamp;
|
SELECT * FROM brin_timestamp_test WHERE a = '1900-01-01'::timestamp;
|
||||||
|
|
||||||
DROP TABLE brin_timestamp_test;
|
DROP TABLE brin_timestamp_test;
|
||||||
@ -655,10 +655,10 @@ CREATE INDEX ON brin_date_test USING brin (a date_minmax_multi_ops) WITH (pages_
|
|||||||
|
|
||||||
SET enable_seqscan = off;
|
SET enable_seqscan = off;
|
||||||
|
|
||||||
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF)
|
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF, BUFFERS OFF)
|
||||||
SELECT * FROM brin_date_test WHERE a = '2023-01-01'::date;
|
SELECT * FROM brin_date_test WHERE a = '2023-01-01'::date;
|
||||||
|
|
||||||
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF)
|
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF, BUFFERS OFF)
|
||||||
SELECT * FROM brin_date_test WHERE a = '1900-01-01'::date;
|
SELECT * FROM brin_date_test WHERE a = '1900-01-01'::date;
|
||||||
|
|
||||||
DROP TABLE brin_date_test;
|
DROP TABLE brin_date_test;
|
||||||
@ -676,10 +676,10 @@ CREATE INDEX ON brin_interval_test USING brin (a interval_minmax_multi_ops) WITH
|
|||||||
|
|
||||||
SET enable_seqscan = off;
|
SET enable_seqscan = off;
|
||||||
|
|
||||||
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF)
|
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF, BUFFERS OFF)
|
||||||
SELECT * FROM brin_interval_test WHERE a = '-30 years'::interval;
|
SELECT * FROM brin_interval_test WHERE a = '-30 years'::interval;
|
||||||
|
|
||||||
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF)
|
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF, BUFFERS OFF)
|
||||||
SELECT * FROM brin_interval_test WHERE a = '30 years'::interval;
|
SELECT * FROM brin_interval_test WHERE a = '30 years'::interval;
|
||||||
|
|
||||||
DROP TABLE brin_interval_test;
|
DROP TABLE brin_interval_test;
|
||||||
@ -695,10 +695,10 @@ CREATE INDEX ON brin_interval_test USING brin (a interval_minmax_multi_ops) WITH
|
|||||||
|
|
||||||
SET enable_seqscan = off;
|
SET enable_seqscan = off;
|
||||||
|
|
||||||
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF)
|
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF, BUFFERS OFF)
|
||||||
SELECT * FROM brin_interval_test WHERE a = '-30 years'::interval;
|
SELECT * FROM brin_interval_test WHERE a = '-30 years'::interval;
|
||||||
|
|
||||||
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF)
|
EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF, BUFFERS OFF)
|
||||||
SELECT * FROM brin_interval_test WHERE a = '30 years'::interval;
|
SELECT * FROM brin_interval_test WHERE a = '30 years'::interval;
|
||||||
|
|
||||||
DROP TABLE brin_interval_test;
|
DROP TABLE brin_interval_test;
|
||||||
|
@ -62,8 +62,8 @@ set track_io_timing = off;
|
|||||||
-- Simple cases
|
-- Simple cases
|
||||||
|
|
||||||
select explain_filter('explain select * from int8_tbl i8');
|
select explain_filter('explain select * from int8_tbl i8');
|
||||||
select explain_filter('explain (analyze) select * from int8_tbl i8');
|
select explain_filter('explain (analyze, buffers off) select * from int8_tbl i8');
|
||||||
select explain_filter('explain (analyze, verbose) select * from int8_tbl i8');
|
select explain_filter('explain (analyze, buffers off, verbose) select * from int8_tbl i8');
|
||||||
select explain_filter('explain (analyze, buffers, format text) select * from int8_tbl i8');
|
select explain_filter('explain (analyze, buffers, format text) select * from int8_tbl i8');
|
||||||
select explain_filter('explain (analyze, buffers, format xml) select * from int8_tbl i8');
|
select explain_filter('explain (analyze, buffers, format xml) select * from int8_tbl i8');
|
||||||
select explain_filter('explain (analyze, serialize, buffers, format yaml) select * from int8_tbl i8');
|
select explain_filter('explain (analyze, serialize, buffers, format yaml) select * from int8_tbl i8');
|
||||||
@ -96,7 +96,7 @@ select explain_filter('explain (analyze, generic_plan) select unique1 from tenk1
|
|||||||
|
|
||||||
-- MEMORY option
|
-- MEMORY option
|
||||||
select explain_filter('explain (memory) select * from int8_tbl i8');
|
select explain_filter('explain (memory) select * from int8_tbl i8');
|
||||||
select explain_filter('explain (memory, analyze) select * from int8_tbl i8');
|
select explain_filter('explain (memory, analyze, buffers off) select * from int8_tbl i8');
|
||||||
select explain_filter('explain (memory, summary, format yaml) select * from int8_tbl i8');
|
select explain_filter('explain (memory, summary, format yaml) select * from int8_tbl i8');
|
||||||
select explain_filter('explain (memory, analyze, format json) select * from int8_tbl i8');
|
select explain_filter('explain (memory, analyze, format json) select * from int8_tbl i8');
|
||||||
prepare int8_query as select * from int8_tbl i8;
|
prepare int8_query as select * from int8_tbl i8;
|
||||||
@ -168,17 +168,17 @@ select explain_filter('explain (verbose) declare test_cur cursor for select * fr
|
|||||||
select explain_filter('explain (verbose) create table test_ctas as select 1');
|
select explain_filter('explain (verbose) create table test_ctas as select 1');
|
||||||
|
|
||||||
-- Test SERIALIZE option
|
-- Test SERIALIZE option
|
||||||
select explain_filter('explain (analyze,serialize) select * from int8_tbl i8');
|
select explain_filter('explain (analyze,buffers off,serialize) select * from int8_tbl i8');
|
||||||
select explain_filter('explain (analyze,serialize text,buffers,timing off) select * from int8_tbl i8');
|
select explain_filter('explain (analyze,serialize text,buffers,timing off) select * from int8_tbl i8');
|
||||||
select explain_filter('explain (analyze,serialize binary,buffers,timing) select * from int8_tbl i8');
|
select explain_filter('explain (analyze,serialize binary,buffers,timing) select * from int8_tbl i8');
|
||||||
-- this tests an edge case where we have no data to return
|
-- this tests an edge case where we have no data to return
|
||||||
select explain_filter('explain (analyze,serialize) create temp table explain_temp as select * from int8_tbl i8');
|
select explain_filter('explain (analyze,buffers off,serialize) create temp table explain_temp as select * from int8_tbl i8');
|
||||||
|
|
||||||
-- Test tuplestore storage usage in Window aggregate (memory case)
|
-- Test tuplestore storage usage in Window aggregate (memory case)
|
||||||
select explain_filter('explain (analyze,costs off) select sum(n) over() from generate_series(1,10) a(n)');
|
select explain_filter('explain (analyze,buffers off,costs off) select sum(n) over() from generate_series(1,10) a(n)');
|
||||||
-- Test tuplestore storage usage in Window aggregate (disk case)
|
-- Test tuplestore storage usage in Window aggregate (disk case)
|
||||||
set work_mem to 64;
|
set work_mem to 64;
|
||||||
select explain_filter('explain (analyze,costs off) select sum(n) over() from generate_series(1,2000) a(n)');
|
select explain_filter('explain (analyze,buffers off,costs off) select sum(n) over() from generate_series(1,2000) a(n)');
|
||||||
-- Test tuplestore storage usage in Window aggregate (memory and disk case, final result is disk)
|
-- Test tuplestore storage usage in Window aggregate (memory and disk case, final result is disk)
|
||||||
select explain_filter('explain (analyze,costs off) select sum(n) over(partition by m) from (SELECT n < 3 as m, n from generate_series(1,2000) a(n))');
|
select explain_filter('explain (analyze,buffers off,costs off) select sum(n) over(partition by m) from (SELECT n < 3 as m, n from generate_series(1,2000) a(n))');
|
||||||
reset work_mem;
|
reset work_mem;
|
||||||
|
@ -21,7 +21,7 @@ declare
|
|||||||
line text;
|
line text;
|
||||||
begin
|
begin
|
||||||
for line in
|
for line in
|
||||||
execute 'explain (analyze, costs off, summary off, timing off) ' || query
|
execute 'explain (analyze, costs off, summary off, timing off, buffers off) ' || query
|
||||||
loop
|
loop
|
||||||
out_line := regexp_replace(line, '\d+kB', 'NNkB', 'g');
|
out_line := regexp_replace(line, '\d+kB', 'NNkB', 'g');
|
||||||
return next;
|
return next;
|
||||||
@ -38,7 +38,7 @@ declare
|
|||||||
element jsonb;
|
element jsonb;
|
||||||
matching_nodes jsonb := '[]'::jsonb;
|
matching_nodes jsonb := '[]'::jsonb;
|
||||||
begin
|
begin
|
||||||
execute 'explain (analyze, costs off, summary off, timing off, format ''json'') ' || query into strict elements;
|
execute 'explain (analyze, costs off, summary off, timing off, buffers off, format ''json'') ' || query into strict elements;
|
||||||
while jsonb_array_length(elements) > 0 loop
|
while jsonb_array_length(elements) > 0 loop
|
||||||
element := elements->0;
|
element := elements->0;
|
||||||
elements := elements - 0;
|
elements := elements - 0;
|
||||||
|
@ -11,7 +11,7 @@ declare
|
|||||||
ln text;
|
ln text;
|
||||||
begin
|
begin
|
||||||
for ln in
|
for ln in
|
||||||
execute format('explain (analyze, costs off, summary off, timing off) %s',
|
execute format('explain (analyze, costs off, summary off, timing off, buffers off) %s',
|
||||||
query)
|
query)
|
||||||
loop
|
loop
|
||||||
if hide_hitmiss = true then
|
if hide_hitmiss = true then
|
||||||
|
@ -1072,7 +1072,7 @@ $$
|
|||||||
DECLARE ln text;
|
DECLARE ln text;
|
||||||
BEGIN
|
BEGIN
|
||||||
FOR ln IN
|
FOR ln IN
|
||||||
EXECUTE 'explain (analyze, timing off, summary off, costs off) ' ||
|
EXECUTE 'explain (analyze, timing off, summary off, costs off, buffers off) ' ||
|
||||||
query
|
query
|
||||||
LOOP
|
LOOP
|
||||||
ln := regexp_replace(ln, '(Memory( Usage)?|Buckets|Batches): \S*', '\1: xxx', 'g');
|
ln := regexp_replace(ln, '(Memory( Usage)?|Buckets|Batches): \S*', '\1: xxx', 'g');
|
||||||
|
@ -12,7 +12,7 @@ declare
|
|||||||
ln text;
|
ln text;
|
||||||
begin
|
begin
|
||||||
for ln in
|
for ln in
|
||||||
execute format('explain (analyze, costs off, summary off, timing off) %s',
|
execute format('explain (analyze, costs off, summary off, timing off, buffers off) %s',
|
||||||
query)
|
query)
|
||||||
loop
|
loop
|
||||||
ln := regexp_replace(ln, 'Maximum Storage: \d+', 'Maximum Storage: N');
|
ln := regexp_replace(ln, 'Maximum Storage: \d+', 'Maximum Storage: N');
|
||||||
@ -465,8 +465,8 @@ set enable_indexonlyscan = off;
|
|||||||
prepare ab_q1 (int, int, int) as
|
prepare ab_q1 (int, int, int) as
|
||||||
select * from ab where a between $1 and $2 and b <= $3;
|
select * from ab where a between $1 and $2 and b <= $3;
|
||||||
|
|
||||||
explain (analyze, costs off, summary off, timing off) execute ab_q1 (2, 2, 3);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute ab_q1 (2, 2, 3);
|
||||||
explain (analyze, costs off, summary off, timing off) execute ab_q1 (1, 2, 3);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute ab_q1 (1, 2, 3);
|
||||||
|
|
||||||
deallocate ab_q1;
|
deallocate ab_q1;
|
||||||
|
|
||||||
@ -474,21 +474,21 @@ deallocate ab_q1;
|
|||||||
prepare ab_q1 (int, int) as
|
prepare ab_q1 (int, int) as
|
||||||
select a from ab where a between $1 and $2 and b < 3;
|
select a from ab where a between $1 and $2 and b < 3;
|
||||||
|
|
||||||
explain (analyze, costs off, summary off, timing off) execute ab_q1 (2, 2);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute ab_q1 (2, 2);
|
||||||
explain (analyze, costs off, summary off, timing off) execute ab_q1 (2, 4);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute ab_q1 (2, 4);
|
||||||
|
|
||||||
-- Ensure a mix of PARAM_EXTERN and PARAM_EXEC Params work together at
|
-- Ensure a mix of PARAM_EXTERN and PARAM_EXEC Params work together at
|
||||||
-- different levels of partitioning.
|
-- different levels of partitioning.
|
||||||
prepare ab_q2 (int, int) as
|
prepare ab_q2 (int, int) as
|
||||||
select a from ab where a between $1 and $2 and b < (select 3);
|
select a from ab where a between $1 and $2 and b < (select 3);
|
||||||
|
|
||||||
explain (analyze, costs off, summary off, timing off) execute ab_q2 (2, 2);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute ab_q2 (2, 2);
|
||||||
|
|
||||||
-- As above, but swap the PARAM_EXEC Param to the first partition level
|
-- As above, but swap the PARAM_EXEC Param to the first partition level
|
||||||
prepare ab_q3 (int, int) as
|
prepare ab_q3 (int, int) as
|
||||||
select a from ab where b between $1 and $2 and a < (select 3);
|
select a from ab where b between $1 and $2 and a < (select 3);
|
||||||
|
|
||||||
explain (analyze, costs off, summary off, timing off) execute ab_q3 (2, 2);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute ab_q3 (2, 2);
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Test runtime pruning with hash partitioned tables
|
-- Test runtime pruning with hash partitioned tables
|
||||||
@ -538,13 +538,13 @@ begin;
|
|||||||
create function list_part_fn(int) returns int as $$ begin return $1; end;$$ language plpgsql stable;
|
create function list_part_fn(int) returns int as $$ begin return $1; end;$$ language plpgsql stable;
|
||||||
|
|
||||||
-- Ensure pruning works using a stable function containing no Vars
|
-- Ensure pruning works using a stable function containing no Vars
|
||||||
explain (analyze, costs off, summary off, timing off) select * from list_part where a = list_part_fn(1);
|
explain (analyze, costs off, summary off, timing off, buffers off) select * from list_part where a = list_part_fn(1);
|
||||||
|
|
||||||
-- Ensure pruning does not take place when the function has a Var parameter
|
-- Ensure pruning does not take place when the function has a Var parameter
|
||||||
explain (analyze, costs off, summary off, timing off) select * from list_part where a = list_part_fn(a);
|
explain (analyze, costs off, summary off, timing off, buffers off) select * from list_part where a = list_part_fn(a);
|
||||||
|
|
||||||
-- Ensure pruning does not take place when the expression contains a Var.
|
-- Ensure pruning does not take place when the expression contains a Var.
|
||||||
explain (analyze, costs off, summary off, timing off) select * from list_part where a = list_part_fn(1) + a;
|
explain (analyze, costs off, summary off, timing off, buffers off) select * from list_part where a = list_part_fn(1) + a;
|
||||||
|
|
||||||
rollback;
|
rollback;
|
||||||
|
|
||||||
@ -567,7 +567,7 @@ declare
|
|||||||
ln text;
|
ln text;
|
||||||
begin
|
begin
|
||||||
for ln in
|
for ln in
|
||||||
execute format('explain (analyze, costs off, summary off, timing off) %s',
|
execute format('explain (analyze, costs off, summary off, timing off, buffers off) %s',
|
||||||
$1)
|
$1)
|
||||||
loop
|
loop
|
||||||
ln := regexp_replace(ln, 'Workers Launched: \d+', 'Workers Launched: N');
|
ln := regexp_replace(ln, 'Workers Launched: \d+', 'Workers Launched: N');
|
||||||
@ -650,15 +650,15 @@ reset min_parallel_table_scan_size;
|
|||||||
reset max_parallel_workers_per_gather;
|
reset max_parallel_workers_per_gather;
|
||||||
|
|
||||||
-- Test run-time partition pruning with an initplan
|
-- Test run-time partition pruning with an initplan
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from ab where a = (select max(a) from lprt_a) and b = (select max(a)-1 from lprt_a);
|
select * from ab where a = (select max(a) from lprt_a) and b = (select max(a)-1 from lprt_a);
|
||||||
|
|
||||||
-- Test run-time partition pruning with UNION ALL parents
|
-- Test run-time partition pruning with UNION ALL parents
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from (select * from ab where a = 1 union all select * from ab) ab where b = (select 1);
|
select * from (select * from ab where a = 1 union all select * from ab) ab where b = (select 1);
|
||||||
|
|
||||||
-- A case containing a UNION ALL with a non-partitioned child.
|
-- A case containing a UNION ALL with a non-partitioned child.
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from (select * from ab where a = 1 union all (values(10,5)) union all select * from ab) ab where b = (select 1);
|
select * from (select * from ab where a = 1 union all (values(10,5)) union all select * from ab) ab where b = (select 1);
|
||||||
|
|
||||||
-- Another UNION ALL test, but containing a mix of exec init and exec run-time pruning.
|
-- Another UNION ALL test, but containing a mix of exec init and exec run-time pruning.
|
||||||
@ -678,7 +678,7 @@ union all
|
|||||||
) ab where a = $1 and b = (select -10);
|
) ab where a = $1 and b = (select -10);
|
||||||
|
|
||||||
-- Ensure the xy_1 subplan is not pruned.
|
-- Ensure the xy_1 subplan is not pruned.
|
||||||
explain (analyze, costs off, summary off, timing off) execute ab_q6(1);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute ab_q6(1);
|
||||||
|
|
||||||
-- Ensure we see just the xy_1 row.
|
-- Ensure we see just the xy_1 row.
|
||||||
execute ab_q6(100);
|
execute ab_q6(100);
|
||||||
@ -733,10 +733,10 @@ insert into tprt values (10), (20), (501), (502), (505), (1001), (4500);
|
|||||||
set enable_hashjoin = off;
|
set enable_hashjoin = off;
|
||||||
set enable_mergejoin = off;
|
set enable_mergejoin = off;
|
||||||
|
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from tbl1 join tprt on tbl1.col1 > tprt.col1;
|
select * from tbl1 join tprt on tbl1.col1 > tprt.col1;
|
||||||
|
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from tbl1 join tprt on tbl1.col1 = tprt.col1;
|
select * from tbl1 join tprt on tbl1.col1 = tprt.col1;
|
||||||
|
|
||||||
select tbl1.col1, tprt.col1 from tbl1
|
select tbl1.col1, tprt.col1 from tbl1
|
||||||
@ -749,10 +749,10 @@ order by tbl1.col1, tprt.col1;
|
|||||||
|
|
||||||
-- Multiple partitions
|
-- Multiple partitions
|
||||||
insert into tbl1 values (1001), (1010), (1011);
|
insert into tbl1 values (1001), (1010), (1011);
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from tbl1 inner join tprt on tbl1.col1 > tprt.col1;
|
select * from tbl1 inner join tprt on tbl1.col1 > tprt.col1;
|
||||||
|
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from tbl1 inner join tprt on tbl1.col1 = tprt.col1;
|
select * from tbl1 inner join tprt on tbl1.col1 = tprt.col1;
|
||||||
|
|
||||||
select tbl1.col1, tprt.col1 from tbl1
|
select tbl1.col1, tprt.col1 from tbl1
|
||||||
@ -766,7 +766,7 @@ order by tbl1.col1, tprt.col1;
|
|||||||
-- Last partition
|
-- Last partition
|
||||||
delete from tbl1;
|
delete from tbl1;
|
||||||
insert into tbl1 values (4400);
|
insert into tbl1 values (4400);
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from tbl1 join tprt on tbl1.col1 < tprt.col1;
|
select * from tbl1 join tprt on tbl1.col1 < tprt.col1;
|
||||||
|
|
||||||
select tbl1.col1, tprt.col1 from tbl1
|
select tbl1.col1, tprt.col1 from tbl1
|
||||||
@ -776,7 +776,7 @@ order by tbl1.col1, tprt.col1;
|
|||||||
-- No matching partition
|
-- No matching partition
|
||||||
delete from tbl1;
|
delete from tbl1;
|
||||||
insert into tbl1 values (10000);
|
insert into tbl1 values (10000);
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from tbl1 join tprt on tbl1.col1 = tprt.col1;
|
select * from tbl1 join tprt on tbl1.col1 = tprt.col1;
|
||||||
|
|
||||||
select tbl1.col1, tprt.col1 from tbl1
|
select tbl1.col1, tprt.col1 from tbl1
|
||||||
@ -799,7 +799,7 @@ prepare part_abc_q1 (int, int, int) as
|
|||||||
select * from part_abc where a = $1 and b = $2 and c = $3;
|
select * from part_abc where a = $1 and b = $2 and c = $3;
|
||||||
|
|
||||||
-- Single partition should be scanned.
|
-- Single partition should be scanned.
|
||||||
explain (analyze, costs off, summary off, timing off) execute part_abc_q1 (1, 2, 3);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute part_abc_q1 (1, 2, 3);
|
||||||
|
|
||||||
deallocate part_abc_q1;
|
deallocate part_abc_q1;
|
||||||
|
|
||||||
@ -819,12 +819,12 @@ select * from listp where b = 1;
|
|||||||
-- which match the given parameter.
|
-- which match the given parameter.
|
||||||
prepare q1 (int,int) as select * from listp where b in ($1,$2);
|
prepare q1 (int,int) as select * from listp where b in ($1,$2);
|
||||||
|
|
||||||
explain (analyze, costs off, summary off, timing off) execute q1 (1,1);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute q1 (1,1);
|
||||||
|
|
||||||
explain (analyze, costs off, summary off, timing off) execute q1 (2,2);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute q1 (2,2);
|
||||||
|
|
||||||
-- Try with no matching partitions.
|
-- Try with no matching partitions.
|
||||||
explain (analyze, costs off, summary off, timing off) execute q1 (0,0);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute q1 (0,0);
|
||||||
|
|
||||||
deallocate q1;
|
deallocate q1;
|
||||||
|
|
||||||
@ -832,13 +832,13 @@ deallocate q1;
|
|||||||
prepare q1 (int,int,int,int) as select * from listp where b in($1,$2) and $3 <> b and $4 <> b;
|
prepare q1 (int,int,int,int) as select * from listp where b in($1,$2) and $3 <> b and $4 <> b;
|
||||||
|
|
||||||
-- Both partitions allowed by IN clause, but one disallowed by <> clause
|
-- Both partitions allowed by IN clause, but one disallowed by <> clause
|
||||||
explain (analyze, costs off, summary off, timing off) execute q1 (1,2,2,0);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute q1 (1,2,2,0);
|
||||||
|
|
||||||
-- Both partitions allowed by IN clause, then both excluded again by <> clauses.
|
-- Both partitions allowed by IN clause, then both excluded again by <> clauses.
|
||||||
explain (analyze, costs off, summary off, timing off) execute q1 (1,2,2,1);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute q1 (1,2,2,1);
|
||||||
|
|
||||||
-- Ensure Params that evaluate to NULL properly prune away all partitions
|
-- Ensure Params that evaluate to NULL properly prune away all partitions
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from listp where a = (select null::int);
|
select * from listp where a = (select null::int);
|
||||||
|
|
||||||
drop table listp;
|
drop table listp;
|
||||||
@ -855,30 +855,30 @@ create table stable_qual_pruning3 partition of stable_qual_pruning
|
|||||||
for values from ('3000-02-01') to ('3000-03-01');
|
for values from ('3000-02-01') to ('3000-03-01');
|
||||||
|
|
||||||
-- comparison against a stable value requires run-time pruning
|
-- comparison against a stable value requires run-time pruning
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from stable_qual_pruning where a < localtimestamp;
|
select * from stable_qual_pruning where a < localtimestamp;
|
||||||
|
|
||||||
-- timestamp < timestamptz comparison is only stable, not immutable
|
-- timestamp < timestamptz comparison is only stable, not immutable
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from stable_qual_pruning where a < '2000-02-01'::timestamptz;
|
select * from stable_qual_pruning where a < '2000-02-01'::timestamptz;
|
||||||
|
|
||||||
-- check ScalarArrayOp cases
|
-- check ScalarArrayOp cases
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from stable_qual_pruning
|
select * from stable_qual_pruning
|
||||||
where a = any(array['2010-02-01', '2020-01-01']::timestamp[]);
|
where a = any(array['2010-02-01', '2020-01-01']::timestamp[]);
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from stable_qual_pruning
|
select * from stable_qual_pruning
|
||||||
where a = any(array['2000-02-01', '2010-01-01']::timestamp[]);
|
where a = any(array['2000-02-01', '2010-01-01']::timestamp[]);
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from stable_qual_pruning
|
select * from stable_qual_pruning
|
||||||
where a = any(array['2000-02-01', localtimestamp]::timestamp[]);
|
where a = any(array['2000-02-01', localtimestamp]::timestamp[]);
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from stable_qual_pruning
|
select * from stable_qual_pruning
|
||||||
where a = any(array['2010-02-01', '2020-01-01']::timestamptz[]);
|
where a = any(array['2010-02-01', '2020-01-01']::timestamptz[]);
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from stable_qual_pruning
|
select * from stable_qual_pruning
|
||||||
where a = any(array['2000-02-01', '2010-01-01']::timestamptz[]);
|
where a = any(array['2000-02-01', '2010-01-01']::timestamptz[]);
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from stable_qual_pruning
|
select * from stable_qual_pruning
|
||||||
where a = any(null::timestamptz[]);
|
where a = any(null::timestamptz[]);
|
||||||
|
|
||||||
@ -898,7 +898,7 @@ create table mc3p2 partition of mc3p
|
|||||||
for values from (2, minvalue, minvalue) to (3, maxvalue, maxvalue);
|
for values from (2, minvalue, minvalue) to (3, maxvalue, maxvalue);
|
||||||
insert into mc3p values (0, 1, 1), (1, 1, 1), (2, 1, 1);
|
insert into mc3p values (0, 1, 1), (1, 1, 1), (2, 1, 1);
|
||||||
|
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from mc3p where a < 3 and abs(b) = 1;
|
select * from mc3p where a < 3 and abs(b) = 1;
|
||||||
|
|
||||||
--
|
--
|
||||||
@ -908,12 +908,12 @@ select * from mc3p where a < 3 and abs(b) = 1;
|
|||||||
--
|
--
|
||||||
prepare ps1 as
|
prepare ps1 as
|
||||||
select * from mc3p where a = $1 and abs(b) < (select 3);
|
select * from mc3p where a = $1 and abs(b) < (select 3);
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
execute ps1(1);
|
execute ps1(1);
|
||||||
deallocate ps1;
|
deallocate ps1;
|
||||||
prepare ps2 as
|
prepare ps2 as
|
||||||
select * from mc3p where a <= $1 and abs(b) < (select 3);
|
select * from mc3p where a <= $1 and abs(b) < (select 3);
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
execute ps2(1);
|
execute ps2(1);
|
||||||
deallocate ps2;
|
deallocate ps2;
|
||||||
|
|
||||||
@ -927,10 +927,10 @@ create table boolp (a bool) partition by list (a);
|
|||||||
create table boolp_t partition of boolp for values in('t');
|
create table boolp_t partition of boolp for values in('t');
|
||||||
create table boolp_f partition of boolp for values in('f');
|
create table boolp_f partition of boolp for values in('f');
|
||||||
|
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from boolp where a = (select value from boolvalues where value);
|
select * from boolp where a = (select value from boolvalues where value);
|
||||||
|
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from boolp where a = (select value from boolvalues where not value);
|
select * from boolp where a = (select value from boolvalues where not value);
|
||||||
|
|
||||||
drop table boolp;
|
drop table boolp;
|
||||||
@ -950,12 +950,12 @@ create index on ma_test (b);
|
|||||||
analyze ma_test;
|
analyze ma_test;
|
||||||
prepare mt_q1 (int) as select a from ma_test where a >= $1 and a % 10 = 5 order by b;
|
prepare mt_q1 (int) as select a from ma_test where a >= $1 and a % 10 = 5 order by b;
|
||||||
|
|
||||||
explain (analyze, costs off, summary off, timing off) execute mt_q1(15);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute mt_q1(15);
|
||||||
execute mt_q1(15);
|
execute mt_q1(15);
|
||||||
explain (analyze, costs off, summary off, timing off) execute mt_q1(25);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute mt_q1(25);
|
||||||
execute mt_q1(25);
|
execute mt_q1(25);
|
||||||
-- Ensure MergeAppend behaves correctly when no subplans match
|
-- Ensure MergeAppend behaves correctly when no subplans match
|
||||||
explain (analyze, costs off, summary off, timing off) execute mt_q1(35);
|
explain (analyze, costs off, summary off, timing off, buffers off) execute mt_q1(35);
|
||||||
execute mt_q1(35);
|
execute mt_q1(35);
|
||||||
|
|
||||||
deallocate mt_q1;
|
deallocate mt_q1;
|
||||||
@ -963,12 +963,12 @@ deallocate mt_q1;
|
|||||||
prepare mt_q2 (int) as select * from ma_test where a >= $1 order by b limit 1;
|
prepare mt_q2 (int) as select * from ma_test where a >= $1 order by b limit 1;
|
||||||
|
|
||||||
-- Ensure output list looks sane when the MergeAppend has no subplans.
|
-- Ensure output list looks sane when the MergeAppend has no subplans.
|
||||||
explain (analyze, verbose, costs off, summary off, timing off) execute mt_q2 (35);
|
explain (analyze, verbose, costs off, summary off, timing off, buffers off) execute mt_q2 (35);
|
||||||
|
|
||||||
deallocate mt_q2;
|
deallocate mt_q2;
|
||||||
|
|
||||||
-- ensure initplan params properly prune partitions
|
-- ensure initplan params properly prune partitions
|
||||||
explain (analyze, costs off, summary off, timing off) select * from ma_test where a >= (select min(b) from ma_test_p2) order by b;
|
explain (analyze, costs off, summary off, timing off, buffers off) select * from ma_test where a >= (select min(b) from ma_test_p2) order by b;
|
||||||
|
|
||||||
reset enable_seqscan;
|
reset enable_seqscan;
|
||||||
reset enable_sort;
|
reset enable_sort;
|
||||||
@ -1148,7 +1148,7 @@ create table listp1 partition of listp for values in(1);
|
|||||||
create table listp2 partition of listp for values in(2) partition by list(b);
|
create table listp2 partition of listp for values in(2) partition by list(b);
|
||||||
create table listp2_10 partition of listp2 for values in (10);
|
create table listp2_10 partition of listp2 for values in (10);
|
||||||
|
|
||||||
explain (analyze, costs off, summary off, timing off)
|
explain (analyze, costs off, summary off, timing off, buffers off)
|
||||||
select * from listp where a = (select 2) and b <> 10;
|
select * from listp where a = (select 2) and b <> 10;
|
||||||
|
|
||||||
--
|
--
|
||||||
@ -1216,7 +1216,7 @@ create table rangep_100_to_200 partition of rangep for values from (100) to (200
|
|||||||
create index on rangep (a);
|
create index on rangep (a);
|
||||||
|
|
||||||
-- Ensure run-time pruning works on the nested Merge Append
|
-- Ensure run-time pruning works on the nested Merge Append
|
||||||
explain (analyze on, costs off, timing off, summary off)
|
explain (analyze on, costs off, timing off, summary off, buffers off)
|
||||||
select * from rangep where b IN((select 1),(select 2)) order by a;
|
select * from rangep where b IN((select 1),(select 2)) order by a;
|
||||||
reset enable_sort;
|
reset enable_sort;
|
||||||
drop table rangep;
|
drop table rangep;
|
||||||
|
@ -196,7 +196,7 @@ explain (costs off)
|
|||||||
select * from onek2 where unique2 = 11 and stringu1 = 'ATAAAA';
|
select * from onek2 where unique2 = 11 and stringu1 = 'ATAAAA';
|
||||||
select * from onek2 where unique2 = 11 and stringu1 = 'ATAAAA';
|
select * from onek2 where unique2 = 11 and stringu1 = 'ATAAAA';
|
||||||
-- actually run the query with an analyze to use the partial index
|
-- actually run the query with an analyze to use the partial index
|
||||||
explain (costs off, analyze on, timing off, summary off)
|
explain (costs off, analyze on, timing off, summary off, buffers off)
|
||||||
select * from onek2 where unique2 = 11 and stringu1 = 'ATAAAA';
|
select * from onek2 where unique2 = 11 and stringu1 = 'ATAAAA';
|
||||||
explain (costs off)
|
explain (costs off)
|
||||||
select unique2 from onek2 where unique2 = 11 and stringu1 = 'ATAAAA';
|
select unique2 from onek2 where unique2 = 11 and stringu1 = 'ATAAAA';
|
||||||
|
@ -30,7 +30,7 @@ SET SESSION AUTHORIZATION regress_selinto_user;
|
|||||||
CREATE TABLE selinto_schema.tbl_withdata1 (a)
|
CREATE TABLE selinto_schema.tbl_withdata1 (a)
|
||||||
AS SELECT generate_series(1,3) WITH DATA;
|
AS SELECT generate_series(1,3) WITH DATA;
|
||||||
INSERT INTO selinto_schema.tbl_withdata1 VALUES (4);
|
INSERT INTO selinto_schema.tbl_withdata1 VALUES (4);
|
||||||
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF)
|
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF, BUFFERS OFF)
|
||||||
CREATE TABLE selinto_schema.tbl_withdata2 (a) AS
|
CREATE TABLE selinto_schema.tbl_withdata2 (a) AS
|
||||||
SELECT generate_series(1,3) WITH DATA;
|
SELECT generate_series(1,3) WITH DATA;
|
||||||
-- WITH NO DATA, passes.
|
-- WITH NO DATA, passes.
|
||||||
@ -49,7 +49,7 @@ EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF)
|
|||||||
-- EXECUTE and WITH NO DATA, passes.
|
-- EXECUTE and WITH NO DATA, passes.
|
||||||
CREATE TABLE selinto_schema.tbl_nodata3 (a) AS
|
CREATE TABLE selinto_schema.tbl_nodata3 (a) AS
|
||||||
EXECUTE data_sel WITH NO DATA;
|
EXECUTE data_sel WITH NO DATA;
|
||||||
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF)
|
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF, BUFFERS OFF)
|
||||||
CREATE TABLE selinto_schema.tbl_nodata4 (a) AS
|
CREATE TABLE selinto_schema.tbl_nodata4 (a) AS
|
||||||
EXECUTE data_sel WITH NO DATA;
|
EXECUTE data_sel WITH NO DATA;
|
||||||
RESET SESSION AUTHORIZATION;
|
RESET SESSION AUTHORIZATION;
|
||||||
|
@ -230,7 +230,7 @@ select count(*) from bmscantest where a>1;
|
|||||||
-- test accumulation of stats for parallel nodes
|
-- test accumulation of stats for parallel nodes
|
||||||
reset enable_seqscan;
|
reset enable_seqscan;
|
||||||
alter table tenk2 set (parallel_workers = 0);
|
alter table tenk2 set (parallel_workers = 0);
|
||||||
explain (analyze, timing off, summary off, costs off)
|
explain (analyze, timing off, summary off, costs off, buffers off)
|
||||||
select count(*) from tenk1, tenk2 where tenk1.hundred > 1
|
select count(*) from tenk1, tenk2 where tenk1.hundred > 1
|
||||||
and tenk2.thousand=0;
|
and tenk2.thousand=0;
|
||||||
alter table tenk2 reset (parallel_workers);
|
alter table tenk2 reset (parallel_workers);
|
||||||
@ -242,7 +242,7 @@ $$
|
|||||||
declare ln text;
|
declare ln text;
|
||||||
begin
|
begin
|
||||||
for ln in
|
for ln in
|
||||||
explain (analyze, timing off, summary off, costs off)
|
explain (analyze, timing off, summary off, costs off, buffers off)
|
||||||
select * from
|
select * from
|
||||||
(select ten from tenk1 where ten < 100 order by ten) ss
|
(select ten from tenk1 where ten < 100 order by ten) ss
|
||||||
right join (values (1),(2),(3)) v(x) on true
|
right join (values (1),(2),(3)) v(x) on true
|
||||||
@ -450,7 +450,7 @@ explain (costs off)
|
|||||||
-- to increase the parallel query test coverage
|
-- to increase the parallel query test coverage
|
||||||
SAVEPOINT settings;
|
SAVEPOINT settings;
|
||||||
SET LOCAL debug_parallel_query = 1;
|
SET LOCAL debug_parallel_query = 1;
|
||||||
EXPLAIN (analyze, timing off, summary off, costs off) SELECT * FROM tenk1;
|
EXPLAIN (analyze, timing off, summary off, costs off, buffers off) SELECT * FROM tenk1;
|
||||||
ROLLBACK TO SAVEPOINT settings;
|
ROLLBACK TO SAVEPOINT settings;
|
||||||
|
|
||||||
-- provoke error in worker
|
-- provoke error in worker
|
||||||
|
@ -857,7 +857,7 @@ $$
|
|||||||
declare ln text;
|
declare ln text;
|
||||||
begin
|
begin
|
||||||
for ln in
|
for ln in
|
||||||
explain (analyze, summary off, timing off, costs off)
|
explain (analyze, summary off, timing off, costs off, buffers off)
|
||||||
select * from (select pk,c2 from sq_limit order by c1,pk) as x limit 3
|
select * from (select pk,c2 from sq_limit order by c1,pk) as x limit 3
|
||||||
loop
|
loop
|
||||||
ln := regexp_replace(ln, 'Memory: \S*', 'Memory: xxx');
|
ln := regexp_replace(ln, 'Memory: \S*', 'Memory: xxx');
|
||||||
|
@ -68,17 +68,17 @@ DECLARE c CURSOR FOR SELECT ctid, * FROM tidscan;
|
|||||||
FETCH NEXT FROM c; -- skip one row
|
FETCH NEXT FROM c; -- skip one row
|
||||||
FETCH NEXT FROM c;
|
FETCH NEXT FROM c;
|
||||||
-- perform update
|
-- perform update
|
||||||
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF)
|
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF, BUFFERS OFF)
|
||||||
UPDATE tidscan SET id = -id WHERE CURRENT OF c RETURNING *;
|
UPDATE tidscan SET id = -id WHERE CURRENT OF c RETURNING *;
|
||||||
FETCH NEXT FROM c;
|
FETCH NEXT FROM c;
|
||||||
-- perform update
|
-- perform update
|
||||||
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF)
|
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF, BUFFERS OFF)
|
||||||
UPDATE tidscan SET id = -id WHERE CURRENT OF c RETURNING *;
|
UPDATE tidscan SET id = -id WHERE CURRENT OF c RETURNING *;
|
||||||
SELECT * FROM tidscan;
|
SELECT * FROM tidscan;
|
||||||
-- position cursor past any rows
|
-- position cursor past any rows
|
||||||
FETCH NEXT FROM c;
|
FETCH NEXT FROM c;
|
||||||
-- should error out
|
-- should error out
|
||||||
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF)
|
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF, BUFFERS OFF)
|
||||||
UPDATE tidscan SET id = -id WHERE CURRENT OF c RETURNING *;
|
UPDATE tidscan SET id = -id WHERE CURRENT OF c RETURNING *;
|
||||||
ROLLBACK;
|
ROLLBACK;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user