Update 2020-08-04:
Since this answer is apparently still being viewed regularly I wanted to provide an update on the situation. We're currently using PG 11 with table partitioning on timestamp
and are easily handling a few billion rows in the table(s). The index-only scans are a life saver and it wouldn't be possible without.
Using PostgreSQL 9.2, I have troubles with slow queries on a relatively large table (200+ million rows). I'm not trying anything crazy, just adding historic values. Below is the query and the query plan output.
My table layout:
Table "public.energy_energyentry"
Column | Type | Modifiers
-----------+--------------------------+-----------------------------------------------------------------
id | integer | not null default nextval('energy_energyentry_id_seq'::regclass)
prop_id | integer | not null
timestamp | timestamp with time zone | not null
value | double precision | not null
Indexes:
"energy_energyentry_pkey" PRIMARY KEY, btree (id)
"energy_energyentry_prop_id" btree (prop_id)
"energy_energyentry_prop_id_timestamp_idx" btree (prop_id, "timestamp")
Foreign-key constraints:
"energy_energyentry_prop_id_fkey" FOREIGN KEY (prop_id) REFERENCES gateway_peripheralproperty(id) DEFERRABLE INITIALLY DEFERRED
The data ranges from 2012-01-01 till now, with new data constantly being added. There are about 2.2k distinct values in the prop_id
foreign key, distributed evenly.
I notice that the row estimates aren't far off, but the cost estimates seem larger by factor 4x. This probably isn't an issue, but is there anything I could do about it?
I expect that disk access might be the issue, since the table isn't in memory all the time.
EXPLAIN ANALYZE
SELECT SUM("value")
FROM "energy_energyentry"
WHERE
"prop_id"=82411
AND "timestamp">'2014-06-11'
AND "timestamp"<'2014-11-11'
;
Aggregate (cost=214481.45..214481.46 rows=1 width=8) (actual time=51504.814..51504.814 rows=1 loops=1) -> Index Scan using energy_energyentry_prop_id_timestamp_idx on energy_energyentry (cost=0.00..214434.08 rows=18947 width=8) (actual time=136.030..51488.321 rows=13578 loops=1) Index Cond: ((prop_id = 82411) AND ("timestamp" > '2014-06-11 00:00:00+00'::timestamp with time zone) AND ("timestamp" < '2014-11-11 00:00:00+00'::timestamp with time zone)) Total runtime: 51504.841 ms
Any suggestions how to make this faster?
I'm also fine with just hearing I didn't do anything weird.
prop_time_idx
, yet the table definition showsentry_prop_id_timestamp_idx
. Is this the same index? Please fix.prop
)? If just a small percentage, maybe an index on("timestamp", prop)
would be better. Multiple indexes with the same leading column(s) (prop
in your case) is also often redundant.