I have this query running on a Postgres 12 server with WHERE datetime BETWEEN datetimeA and datetimeB. Time difference between datetimeA and datetimeB is always 30 minutes, number of data involved is not much different, but the execution time for differs wildly:
- WHERE servertime between '2022-12-01 04:00:00' and '2022-12-01 04:30:00'(5 seconds)
- WHERE servertime between '2022-12-29 04:00:00' and '2022-12-29 04:30:00'(4 minutes)
Execution time for beginning of the month date is always fast and it get so much slower as the date near the end of the month.
Below is the full query:
select p2.id as positionid, p2.stationid, p.servertime, p.servertime_max, p.geofenceid 
, p2.latitude, p2.longitude, datanum 
from( 
                select min(p.servertime) as servertime, max(p.servertime) as servertime_max 
                , p.deviceid, count(p.id) as datanum, p.geofenceid                  
                from tc_positions p 
                join tc_devices d on d.id=p.deviceid 
                join tc_stations st on st.id=p.stationid 
                where 
                p.speed <= 50 
                and st.stationcategory=200 
                and servertime between '2022-12-28 04:00:00' and  '2022-12-28 04:30:00'
                group by p.deviceid, p.geofenceid, p.stationid
                    --total data involved 180 rows
) p 
join ( 
                select * from tc_positions where            
                servertime between '2022-12-28 04:00:00' and  '2022-12-28 04:30:00'
                --total data involved 13.000 rows 
) p2 on p2.servertime=p.servertime and p2.deviceid=p.deviceid and p2.geofenceid=p.geofenceid 
where datanum>0;
I stopped all other connections and processes to the DB while testing the queries and running the query on the same date but using different WHERE condition (it doesn't matter WHEN I run the query, if the date range in the condition is small date is always fast despite the fact that the db server is currently handling heavy read/write connection).
Why this behaviour? Probably there are internal Postgres indexing or anything that might make the query run like this. I wish to make the execution time is at least the same for any date as long as the time range is the same.
 
    