Postgresql
PostgreSQL 查詢需要很長時間(因為它沒有使用索引)
這個查詢需要很長時間,因為我猜它正在執行全表掃描。它在 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