Question

I have simple query like this:

SELECT  *
FROM    t1
WHERE   f1 > 42
        AND f2 = 'foo'
        AND f3 = 'bar'
ORDER BY f4 DESC 
LIMIT 10 OFFSET 100;

I have index for field f4 (for other queries). Condition "f1 > 42 AND f2 = 'foo' AND f3 = 'bar'" is not representative and corresponds to 70% of records in table t1. It's about 2 000 000 records in table and it is growing up every day. Query plan explanation for this query shows using of seq scan by entire table and then performing ordering and limitation.

Is it possible to say Postgres to perform this query thus way:

  1. Iterate through reverse ordered rows by using index on field f4.
  2. For each row do comparison with condition f1 > 42 AND f2 = 'foo' AND f3 = 'bar' and take it if corresponded.
  3. If result set size greater than limit stop iterate.
Was it helpful?

Solution

Here are the configurations for the query planner. You can manipulate them to change the query plan (For your case it can be simple SET enable_seqscan = off; for this query).

But before you change the planner configuration - check if statistics on this table are correct and collect them again if needed.

OTHER TIPS

As far as I understand the goal is not only to change execution plan manually but continue to get execution plans similar as on production. In this case game with optimizer definitions is not completely reliable. Taking into consideration that data is continuously growing I would like to recommend partitions implementation on production and development, that will stabilize execution plan. This will leave less possibilities to make mistake in execution plan generation. As an alternative table might be clustered periodically by index on f4. Unfortunately it's not enough information to recommend exactly partitioning strategy.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top