Postgresql

PostgreSQL 查詢需要很長時間(因為它沒有使用索引)

  • February 4, 2021

這個查詢需要很長時間,因為我猜它正在執行全表掃描。它在 Oracle 中可以正常工作,只是在 Postgres 12 中不行。

select count(*)
FROM EVENT 
WHERE PK_EVENT > (select CHECKPOINT1_PKEVENT FROM SYSTEM_CONTROL) 

但是,如果我執行這個,它會在幾秒鐘內返回。

select count(*)
FROM EVENT 
WHERE PK_EVENT > (1000755073)

PK_EVENT和**CHECKPOINT1_PKEVENT列都定義為“int8”,因為它們可能會變得非常大。EVENT.PK_EVENT是主鍵。我已經嘗試重新安排查詢,但到目前為止沒有任何效果。count(*) 只產生 2537 行,即今天在我們的測試 Pg 數據庫上生成的行數。

查詢計劃:

使用 system_control:-

Finalize Aggregate  (cost=2909961.80..2909961.81 rows=1 width=8)
 InitPlan 1 (returns $0)
   ->  Seq Scan on system_control  (cost=0.00..1.01 rows=1 width=8)
 ->  Gather  (cost=2909960.58..2909960.79 rows=2 width=8)
       Workers Planned: 2
       Params Evaluated: $0
       ->  Partial Aggregate  (cost=2908960.58..2908960.59 rows=1 width=8)
             ->  Parallel Seq Scan on event  (cost=0.00..2866882.04 rows=16831415 width=0)
                   Filter: (pk_event > $0)
JIT:
 Functions: 8
 Options: Inlining true, Optimization true, Expressions true, Deforming true

使用硬編碼值:-

Aggregate  (cost=11.42..11.43 rows=1 width=8)
 ->  Index Only Scan using event_pkey on event  (cost=0.57..11.36 rows=25 width=0)
       Index Cond: (pk_event > 1000755073)

整個查詢是預先計劃好的,在計劃時它不知道在 CHECKPOINT1_PKEVENT 中會找到什麼值。它一般假設不等式將匹配 1/3 的行,這顯然是完全錯誤的。面對這種情況,我通常只讓客戶端軟體單獨執行查詢,將一個結果填充到另一個參數中,假設我可以容忍兩次執行之間值可能發生變化的前景。

也就是說,無論如何它可能應該只進行索引掃描。您對 random_page_cost 的設置是否很高?您還有哪些其他規劃器設置?表 EVENT 最近是否被清理過?

您應該包含EXPLAIN,以便我們可以看到引擎蓋下發生了什麼。如果您像這個邏輯等價物一樣重新編寫查詢,會有什麼不同嗎?

SELECT COUNT(*)
FROM EVENT E
INNER JOIN SYSTEM_CONTROL S
   ON E.PK_EVENT > S.CHECKPOINT1_PKEVENT

引用自:https://dba.stackexchange.com/questions/284605