title: How do I speed up this Django PostgreSQL query?
body: <p>I'm trying to speed up what seems to me to be quite a slow PostgreSQL query in Django (150ms)</p>
  
  <p>This is the query:</p>
  
  <pre><code>SELECT ••• FROM "predictions_prediction"
  INNER JOIN "minute_in_time_minute"
  ON ( "predictions_prediction"."minute_id" = "minute_in_time_minute"."id" )
  WHERE ("minute_in_time_minute"."datetime" &gt;= '2014-08-21 13:12:00+00:00'
  AND "predictions_prediction"."location_id" = 1
  AND "minute_in_time_minute"."datetime" &lt; '2014-08-24 13:12:00+00:00'
  AND "predictions_prediction"."tide_level" &gt;= 3.0)
  ORDER BY "minute_in_time_minute"."datetime" ASC
  </code></pre>
  
  <p>Here's the result of the PostgreSQL EXPLAIN: </p>
  
  <pre><code>Sort  (cost=17731.45..17739.78 rows=3331 width=32) (actual time=151.755..151.901 rows=3515 loops=1)
    Sort Key: minute_in_time_minute.datetime
    Sort Method: quicksort  Memory: 371kB
    -&gt;  Hash Join  (cost=3187.44..17536.56 rows=3331 width=32) (actual time=96.757..150.693 rows=3515 loops=1)
          Hash Cond: (predictions_prediction.minute_id = minute_in_time_minute.id)
          -&gt;  Seq Scan on predictions_prediction  (cost=0.00..11232.00 rows=411175 width=20) (actual time=0.017..88.063 rows=410125 loops=1)
                Filter: ((tide_level &gt;= 3::double precision) AND (location_id = 1))
                Rows Removed by Filter: 115475
          -&gt;  Hash  (cost=3134.21..3134.21 rows=4258 width=12) (actual time=9.221..9.221 rows=4320 loops=1)
                Buckets: 1024  Batches: 1  Memory Usage: 203kB
                -&gt;  Bitmap Heap Scan on minute_in_time_minute  (cost=92.07..3134.21 rows=4258 width=12) (actual time=1.147..8.220 rows=4320 loops=1)
                      Recheck Cond: ((datetime &gt;= '2014-08-21 13:18:00+00'::timestamp with time zone) AND (datetime &lt; '2014-08-24 13:18:00+00'::timestamp with time zone))
                      -&gt;  Bitmap Index Scan on minute_in_time_minute_datetime_key  (cost=0.00..91.00 rows=4258 width=0) (actual time=0.851..0.851 rows=4320 loops=1)
                            Index Cond: ((datetime &gt;= '2014-08-21 13:18:00+00'::timestamp with time zone) AND (datetime &lt; '2014-08-24 13:18:00+00'::timestamp with time zone))
  </code></pre>
  
  <p>I've tried visualising it in an external tool (<a href="http://explain.depesz.com/s/CWW" rel="nofollow">http://explain.depesz.com/s/CWW</a>) which shows that the start of the problem is the <code>Seq Scan on predictions_prediction</code></p>
  
  <p>What I've tried so far:</p>
  
  <ul>
  <li>Add an index on <code>predictions_prediction.tide_level</code></li>
  <li>Add a composite index on <code>tide_level</code> and <code>location</code> on <code>predictions.prediction</code></li>
  </ul>
  
  <p>But neither had any effect as far as I could see.</p>
  
  <p>Can someone please help me interpret the query plan?</p>
  
  <p>Thanks</p>