Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting enable_seqscan = off in a single SELECT query

After several tests on one of my queries (Postgres) I realized that by setting enable_seqscan = off, the query takes 1/3 of its original time (done using the psql console and EXPLAIN ANALYZE)

Since it is not recommendable to change this setting for the whole server, I want to set it to OFF only for this query.
How can I do it? Is it possible?

My implementation is based on framework Kohana (PHP), which uses a DB object ( DB::select ) to execute the query.

My postgres is 8.4.9 on a CentOS Linux.

like image 488
juakonn Avatar asked Mar 01 '13 19:03

juakonn


People also ask

How do I stop index scan in postgresql?

To prevent Postgres using an index only scan we select more columns than the index contains. The index scan is much faster. The next step is to look at the the query by changing the condition to match all rows. An index scan is still faster, but the percentage of the difference is far smaller.

What is enable_ seqscan?

enable_seqscan ( boolean ) Enables or disables the query planner's use of sequential scan plan types. It is impossible to suppress sequential scans entirely, but turning this variable off discourages the planner from using one if there are other methods available. The default is on .

What is random page cost in postgresql?

The default is 4.0. This value can be overridden for tables and indexes in a particular tablespace by setting the tablespace parameter of the same name (see sql-altertablespace).


1 Answers

You can use SET LOCAL in your transaction for that. I quote the manual:

The effects of SET LOCAL last only till the end of the current transaction, whether committed or not.

But that's like eating antibiotics when you keep getting sick instead of finding the cause. Normally, there is a reason why the planner picks a suboptimal plan. You should find and fix that. See:

  • Keep PostgreSQL from sometimes choosing a bad query plan

I suspect a lower setting for random_page_cost might work for you. The default setting is regularly too conservative (too high). If most or all of your DB is cached (the system cache does that for whatever gets used repeatedly and fits into RAM), random_page_cost can be almost as low (or in extreme cases just as low) as seq_page_cost. random_page_cost is a major factor in calculating the cost of index usage.

Be sure that autovacuum is running and properly configured (takes care of VACUUM and ANALYZE). You need column statistics to be up to date for proper query planning.

And effective_cache_size is regularly set too low out of the box.

Exceptions apply, and sometimes the query planner just doesn't get it, especially with older versions. Which brings me to another delicate point here: upgrade to a current version of PostgreSQL. Yours is out of date.

like image 150
Erwin Brandstetter Avatar answered Oct 12 '22 21:10

Erwin Brandstetter