Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <pre><code>SET search_path=tmp; -- ------------------------------------------- -- create table and populate it with 10M rows -- ------------------------------------------- DROP SCHEMA tmp CASCADE; CREATE SCHEMA tmp ; SET search_path=tmp; CREATE TABLE old_echo ( the_time timestamp NOT NULL PRIMARY KEY , payload DOUBLE PRECISION NOT NULL ); INSERT INTO old_echo (the_time, payload) SELECT now() - (gs * interval '1 msec') , random() FROM generate_series(1,10000000) gs ; -- DELETE FROM old_echo WHERE random() &lt; 0.8; VACUUM ANALYZE old_echo; SELECT MIN(the_time) AS first , MAX(the_time) AS last , (MAX(the_time) - MIN(the_time))::interval AS width FROM old_echo ; EXPLAIN ANALYZE SELECT * FROM old_echo oe JOIN ( SELECT MIN(the_time) AS first , MAX(the_time) AS last , (MAX(the_time) - MIN(the_time))::interval AS width , ((MAX(the_time) - MIN(the_time))/2)::interval AS half FROM old_echo ) mima ON 1=1 WHERE oe.the_time &gt;= mima.first + mima.half AND oe.the_time &lt; mima.first + mima.half + '1 sec':: interval ; </code></pre> <p>RESULT:</p> <pre><code> QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Nested Loop (cost=0.06..59433.67 rows=1111124 width=64) (actual time=0.101..1.307 rows=1000 loops=1) -&gt; Result (cost=0.06..0.07 rows=1 width=0) (actual time=0.049..0.050 rows=1 loops=1) InitPlan 1 (returns $0) -&gt; Limit (cost=0.00..0.03 rows=1 width=8) (actual time=0.022..0.022 rows=1 loops=1) -&gt; Index Scan using old_echo_pkey on old_echo (cost=0.00..284873.62 rows=10000115 width=8) (actual time=0.021..0.021 rows=1 loops=1) Index Cond: (the_time IS NOT NULL) InitPlan 2 (returns $1) -&gt; Limit (cost=0.00..0.03 rows=1 width=8) (actual time=0.009..0.010 rows=1 loops=1) -&gt; Index Scan Backward using old_echo_pkey on old_echo (cost=0.00..284873.62 rows=10000115 width=8) (actual time=0.009..0.009 rows=1 loops=1) Index Cond: (the_time IS NOT NULL) -&gt; Index Scan using old_echo_pkey on old_echo oe (cost=0.01..34433.30 rows=1111124 width=16) (actual time=0.042..0.764 rows=1000 loops=1) Index Cond: ((the_time &gt;= (($0) + ((($1 - $0) / 2::double precision)))) AND (the_time &lt; ((($0) + ((($1 - $0) / 2::double precision))) + '00:00:01'::interval))) Total runtime: 1.504 ms (13 rows) </code></pre> <p>UPDATE: since the timestamp appears to be non-unique (btw: what do duplicates <em>mean</em> in that case?) I added an extra key column. An ugly hack, but it works here. query time 11ms for 10M -80% rows. (number of rows hit 210/222067):</p> <pre><code>CREATE TABLE old_echo ( the_time timestamp NOT NULL , the_seq SERIAL NOT NULL -- to catch the duplicate keys , payload DOUBLE PRECISION NOT NULL , PRIMARY KEY(the_time, the_seq) ); -- Adding the random will cause some timestamps to be non-unique. -- (and others to be non-existent) INSERT INTO old_echo (the_time, payload) SELECT now() - ((gs+random()*1000::integer) * interval '1 msec') , random() FROM generate_series(1,10000000) gs ; DELETE FROM old_echo WHERE random() &lt; 0.8; </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload