【发布时间】:2022-01-22 05:51:34
【问题描述】:
我有一个大型查询,我正在尝试分析以提高效率。我第一次跑只是EXPLAIN:
EXPLAIN
SELECT * FROM pop_allocation_sql.main_parcels_cb_intersects
WHERE parcel_id NOT IN (SELECT DISTINCT parcel_id::int
FROM pop_allocation_sql.main_bldgs_cb_intersects)
它在几秒钟内返回以下内容:
Gather (cost=20506897.97..3330358572517.40 rows=40283932 width=89)
Workers Planned: 7
-> Parallel Seq Scan on main_parcels_cb_intersects (cost=20505897.97..3330354543124.20 rows=5754847 width=89)
Filter: (NOT (SubPlan 1))
SubPlan 1
-> Materialize (cost=20505897.97..21069329.24 rows=6107669 width=4)
-> Unique (cost=20505897.97..21014931.89 rows=6107669 width=4)
-> Sort (cost=20505897.97..20760414.93 rows=101806784 width=4)
Sort Key: ((main_bldgs_cb_intersects.parcel_id)::integer)
-> Seq Scan on main_bldgs_cb_intersects (cost=0.00..5334454.80 rows=101806784 width=4)
但这不会告诉我确切的瓶颈发生在哪里,所以我尝试运行:
EXPLAIN ANALYZE
SELECT * FROM pop_allocation_sql.main_parcels_cb_intersects
WHERE parcel_id NOT IN (SELECT DISTINCT parcel_id::int
FROM pop_allocation_sql.main_bldgs_cb_intersects)
我让它运行了一个多小时,但没有任何返回。我检查了 PG ADMIN 并注意到等待事件说 Lock: transactionid 并给出了 119698 的阻塞 PID(我不确定这意味着什么)。为什么我的查询没有完成?
【问题讨论】:
-
Explain 只给出一个计划估计,analyze 会实际运行它。该查询表现不佳,但 pgadmin 说有另一个事务正在修改该查询试图读取的行。该查询尚未提交,因此挂起。
-
子选择中的
distinct是不必要的。通常,等效的 NOT EXISTS 条件比 NOT IN 更快,因此请尝试重新编写查询。 -
@VynlJunkie:这里肯定还有更多事情要做。 SELECT 查询不会被其他查询阻止,除非例如对该表运行了 TRUNCATE。
标签: postgresql query-optimization sql-execution-plan explain