postgresql - 有什么方法可以提高具有多个连接的查询的性能?
问题描述
我有以下具有 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 = ?;
以下是解释分析结果
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 驱动器会有帮助吗?
解决方案
问题在这里:
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>
ps 在新行上放宽,并在 FROM 之后证明一切都将有助于提高可读性。
推荐阅读
- react-native - 从 useEffect 挂钩调度时,Redux 数组状态未更新
- delphi - 重新启动后 MoveFileEx 不删除文件
- javascript - Zul 页面中的 Reactjs 库
- java - 每天在特定时间做某事
- html - 如何使我的图像缩放适合新的边界?
- javascript - 我需要切换常见问题页面的显示设置。我制作了一个有效的 js 脚本,但它非常重复,我该如何简化呢?
- javascript - 数千次写入 MongoDB 后,NodeJS 崩溃
- python - 初学者问题 - 我只知道 python,我如何使用 API?
- python - 使用多个数据集训练神经网络 (Keras)
- python - Numba 数据类型错误:无法统一数组