0

I have an index on car_id and an index on ended_at.

Is this query taking so long because I am ordering it by id and I have separate unique indexes?

Would it be better if I ordered it by ended_at and then made an index on both ended_at and car_id?

SELECT  "trip_reports".*
FROM "trip_reports"
WHERE "trip_reports"."car_id" = $1 AND (ended_at < '2020-11-03 17:31:09')
ORDER BY "trip_reports"."id" DESC
LIMIT $2

Duration is 6.05 minutes.

The query plan:

Limit (cost=0.56..4512.17 rows=1 width=1156)
  -> Index Scan Backward using trip_reports_pkey on trip_reports (cost=0.56..9830786.80 rows=2179 width=1156)
     Filter: ((ended_at < '2020-11-03 20:55:57'::timestamp without time zone) AND (car_id = 103638))

EXPLAIN (ANALYZE, BUFFERS)

Limit  (cost=0.56..4512.67 rows=1 width=1156) (actual time=976974.363..976974.363 rows=0 loops=1)
  Buffers: shared hit=2071575 read=3222036
  ->  Index Scan Backward using trip_reports_pkey on trip_reports  (cost=0.56..9831877.02 rows=2179 width=1156) (actual time=976974.361..976974.361 rows=0 loops=1)
        Filter: ((ended_at < '2020-11-03 17:31:09'::timestamp without time zone) AND (car_id = 119780))
        Rows Removed by Filter: 22862225
        Buffers: shared hit=2071575 read=3222036
Planning time: 0.113 ms
Execution time: 976975.711 ms
4
  • 1
    We'd need the result of EXPLAIN (ANALYZE, BUFFERS) for the query to give an answer. Commented Nov 4, 2020 at 14:13
  • 2
    Try a multi-column index. (Your query will only use one index.) Commented Nov 4, 2020 at 14:32
  • @LaurenzAlbe Posted EXPLAIN (ANALYZE, BUFFERS). Commented Nov 4, 2020 at 14:45
  • @jarlh Ok, I will try. Is this because it has an Order By in the query? Commented Nov 4, 2020 at 14:45

1 Answer 1

2

In my opinion:

  1. Try creating an index for the WHERE condition:

    create index trip_reports_carid_endtime on trip_reports (car_id, ended_at);
    

    (column order in index is important)

  2. If you did not do it before:

    vacuum (analyse) trip_reports;
    
Sign up to request clarification or add additional context in comments.

2 Comments

how can I vacuum asynchronously?
postgres use few "workers" to do vacuum - number of max workers is parameter max_parallel_maintenance_workers

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.