我有以下具有6个联接的查询
EXPLAIN ANALYZE
SELECT
property.id,
full_address,
street_address,
street.street,
city.city as city,
state.state_code as state_code,
zipcode.zipcode as zipcode,
property_tax_history.tax AS property_tax,
property_tax_history.land AS land_value,
property_tax_history.improvements AS improvements_value,
property_tax_history.year AS tax_year,
property_sale_history.date_event AS event_date,
property_sale_history.event AS event,
property_sale_history.price AS event_price
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
LEFT JOIN
property_sale_history
ON property_sale_history.property_id = property.id
LEFT JOIN
property_tax_history
ON property_tax_history.property_id = property.id
WHERE
full_address = ?;
以下是EXPLAIN ANALYZE结果
Nested Loop Left Join (cost=2.83..296.67 rows=6 width=227) (actual time=0.606..0.766 rows=28 loops=1)
-> Nested Loop Left Join (cost=2.26..62.52 rows=1 width=299) (actual time=0.544..0.551 rows=4 loops=1)
-> Nested Loop (cost=1.83..41.98 rows=1 width=284) (actual time=0.522..0.525 rows=1 loops=1)
-> Nested Loop (cost=1.54..33.67 rows=1 width=294) (actual time=0.482..0.485 rows=1 loops=1)
-> Nested Loop (cost=1.27..25.32 rows=1 width=307) (actual time=0.439..0.441 rows=1 loops=1)
-> Nested Loop (cost=0.98..17.02 rows=1 width=314) (actual time=0.392..0.394 rows=1 loops=1)
-> Index Scan using property_full_address on property (cost=0.56..8.57 rows=1 width=318) (actual time=0.339..0.340 rows=1 loops=1)
Index Cond: (full_address = '10951097-4Th-Ave-Chula-Vista-CA-91911'::citext)
-> Index Scan using street_pkey on street (cost=0.42..8.44 rows=1 width=28) (actual time=0.046..0.046 rows=1 loops=1)
Index Cond: (id = property.street_id)
-> Index Scan using city_id_pk on city (cost=0.29..8.30 rows=1 width=25) (actual time=0.044..0.044 rows=1 loops=1)
Index Cond: (id = property.city_id)
-> Index Scan using state_id_pk on state (cost=0.28..8.32 rows=1 width=19) (actual time=0.041..0.041 rows=1 loops=1)
Index Cond: (id = property.state_id)
-> Index Scan using zipcode_id_pk on zipcode (cost=0.29..8.30 rows=1 width=22) (actual time=0.037..0.037 rows=1 loops=1)
Index Cond: (id = property.zipcode_id)
-> Index Scan using property_sale_history_property_id on property_sale_history (cost=0.43..20.50 rows=4 width=31) (actual time=0.019..0.021 rows=4 loops=1)
Index Cond: (property_id = property.id)
-> Index Scan using property_tax_history_property_id on property_tax_history (cost=0.56..233.54 rows=57 width=33) (actual time=0.014..0.021 rows=7 loops=4)
Index Cond: (property_id = property.id)
Planning Time: 9.805 ms
Execution Time: 1.628 ms
有这么多的联接,我可以看到每个联接都需要一些时间,并且它们加起来。无论如何,我可以修改查询来加快速度吗?使用SSD驱动器会有所帮助吗?
答案 0 :(得分:1)
问题在这里:
LEFT JOIN property_sale_history ON property_sale_history.property_id = property.id
LEFT JOIN property_tax_history ON property_tax_history.property_id = property.id
每个表都有独立的联接,并且两个联接的列都在结果中。
这将导致n 2 问题,并返回行数。例如,如果给定属性有3个销售行和4个税收行,则结果中该属性将有12行。这确实会损害性能,并且无法“解决”性能问题,而且这样的查询也毫无意义。
您应该使用两个单独的查询-一个用于销售历史,一个用于税收历史。
您可以考虑为两个查询的共同部分创建视图。
-
p.s。放宽对新行的注释,并在FROM后面保留所有内容的合理性将有助于提高可读性。