0

I have the following SQL query

EXPLAIN ANALYZE 
SELECT
   full_address,
   street_address,
   street.street,
   (
      select
         city 
      from
         city 
      where
         city.id = property.city_id
   )
   AS city,
   (
      select
         state_code 
      from
         state 
      where
         id = property.state_id
   )
   AS state_code,
   (
      select
         zipcode 
      from
         zipcode 
      where
         zipcode.id = property.zipcode_id
   )
   AS zipcode 
FROM
   property 
   INNER JOIN
      street 
      ON street.id = property.street_id 
WHERE
   street.street = 'W San Miguel Ave' 
   AND property.zipcode_id = 
   (
      SELECT
         id 
      FROM
         zipcode 
      WHERE
         zipcode = '85340'
   )

Below is the EXPLAIN ANALYZE results

Gather  (cost=1008.86..226541.68 rows=1 width=161) (actual time=59.311..21956.143 rows=184 loops=1)
  Workers Planned: 2
  Params Evaluated: $3
  Workers Launched: 2
  InitPlan 4 (returns $3)
    ->  Index Scan using zipcode_zipcode_county_id_state_id_index on zipcode zipcode_1  (cost=0.28..8.30 rows=1 width=16) (actual time=0.039..0.040 rows=1 loops=1)
          Index Cond: (zipcode = '85340'::citext)
  ->  Nested Loop  (cost=0.56..225508.35 rows=1 width=113) (actual time=7430.172..14723.451 rows=61 loops=3)
        ->  Parallel Seq Scan on street  (cost=0.00..13681.63 rows=1 width=28) (actual time=108.023..108.053 rows=1 loops=3)
              Filter: (street = 'W San Miguel Ave'::citext)
              Rows Removed by Filter: 99131
        ->  Index Scan using property_street_address_street_id_city_id_state_id_zipcode_id_c on property  (cost=0.56..211826.71 rows=1 width=117) (actual time=10983.195..21923.063 rows=92 loops=2)
              Index Cond: ((street_id = street.id) AND (zipcode_id = $3))
  SubPlan 1
    ->  Index Scan using city_id_pk on city  (cost=0.28..8.30 rows=1 width=9) (actual time=0.003..0.003 rows=1 loops=184)
          Index Cond: (id = property.city_id)
  SubPlan 2
    ->  Index Scan using state_id_pk on state  (cost=0.27..8.34 rows=1 width=3) (actual time=0.002..0.002 rows=1 loops=184)
          Index Cond: (id = property.state_id)
  SubPlan 3
    ->  Index Scan using zipcode_id_pk on zipcode  (cost=0.28..8.30 rows=1 width=6) (actual time=0.002..0.003 rows=1 loops=184)
          Index Cond: (id = property.zipcode_id)
Planning Time: 1.228 ms
Execution Time: 21956.246 ms

Is it possible to speed up this query by adding more indexes?

0

1 Answer 1

1

The query can be rewritten using joins rather than subselects. This may be faster and easier to index.

SELECT
   full_address,
   street_address,
   street.street,
   city.city as city,
   state.state_code as state_code,
   zipcode.zipcode as zipcode,
FROM
    property 
    INNER JOIN street  ON street.id = property.street_id 
    INNER JOIN city    ON city.id = property.city_id
    INNER JOIN state   ON state.id = property.state_id
    INNER JOIN zipcode ON zipcode.id = property.zipcode_id
WHERE
    street.street = 'W San Miguel Ave' 
    AND zipcode.zipcode = '85340'

Assuming all the foreign keys (property.street_id, property.city_id, etc...) are indexed this now becomes a search on street.street and zipcode.zipcode. As long as they are indexed the query should take milliseconds.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks, that did speed things up. Now it takes less than 2 milliseconds. I converted another query from sub-queries to joins to speed it up and it got slower. This is the version that uses sub queries pastebin.com/49igKja2 execution time is 1.309 ms and this is the join version pastebin.com/vZEsVEgC and it takes 89.737 ms. Any idea why in this case using joins is slower?
@Arya Possibly has to do with how full_address is indexed. I can't say more without seeing the indexes and result of explain analyze.
This is the EXPLAIN ANALYZE for the one that uses sub queries pastebin.com/BA5hryqe and this is the EXPLAIN ANALYZE for the one with joins pastebin.com/hZ8XGUsV
@Arya That's a poor query plan for the joins. It's only using the indexes on state.id and property.full_address. It's doing full table scans of street, city, and zipcode. Maybe try analyzing the other tables?

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.