Here is the query:
SELECT "products".*
FROM "products"
WHERE (status > 100)
AND "products"."above_revenue_average" = 't'
AND ("products"."category_id" NOT IN (5))
ORDER BY "products"."start_date" DESC
I have an index on status
and start_date
.
Each time I run the query from my application, I get the following in the logs:
[WHITE] temporary file:
path "pg_tblspc/16386/PG_9.3_201306121/pgsql_tmp/pgsql_tmp2544.0", size 37093376
Query: SELECT "products".* FROM "products" WHERE (status > 100)
AND "products"."above_revenue_average" = 't'
AND ("products"."category_id" NOT IN (5)) ORDER BY "products"."start_date" DESC
I believe this temporary file creation is the cause of the slow performance.
Running an EXPLAIN ANALYZE
I get the following results:
QUERY PLAN
Sort (cost=63395.28..63403.51 rows=16460 width=524)
(actual time=524.134..562.635 rows=65294 loops=1)
Sort Key: start_date
Sort Method: external merge Disk: 36224kB
-> Bitmap Heap Scan on products
(cost=4803.40..60389.73 rows=16460 width=524)
(actual time=27.390..397.879 rows=65294 loops=1)
Recheck Cond: (status > 100)
Filter: (above_revenue_average AND (category_id <> 5))
Rows Removed by Filter: 25115
-> Bitmap Index Scan on index_products_on_status
(cost=0.00..4802.58 rows=89662 width=0)
(actual time=18.006..18.006 rows=90411 loops=1)
Index Cond: (status > 100)
Total runtime: 577.870 ms
(10 rows)
I have then used http://explain.depesz.com/ to make it a bit more readable:
Per node type stats
+-------------------+-------+--------------+------------+
| node type | count | sum of times | % of query |
+-------------------+-------+--------------+------------+
| Bitmap Heap Scan | 1 | 379.873 ms | 67.5 % |
| Bitmap Index Scan | 1 | 18.006 ms | 3.2 % |
| Sort | 1 | 164.756 ms | 29.3 % |
+-------------------+-------+--------------+------------+
Per table stats
+------------------+------------+--------------+------------+
| Table name | Scan count | Total time | % of query |
+------------------+------------+--------------+------------+
| scan type | count | sum of times | % of table |
| products | 1 | 379.873 ms | 67.5 % |
| Bitmap Heap Scan | 1 | 379.873 ms | 100.0 % |
+------------------+------------+--------------+------------+
Can I increase the database performance by adding some more indexes? Maybe some composite ones? Any ideas?
EXPLAIN (BUFFERS, ANALYZE)
produces more information relevant to the case (like instructed in the tag info for [postgresql-performance]. Please always provide your version of Postgres. Also, a single query does not tell us which of your predicates (WHERE
conditions) are immutable and which vary (in what way?). We cannot seriously advice how to optimize indexes without some more information.