Postgresql

PostgreSQL 查詢成本高

  • October 29, 2021

我有一個包含超過 10.000.000 條記錄的表,我正在創建一個返回大約 4436 條記錄的查詢。

碰巧它給我的印像是到達最後一條記錄的查詢成本非常高。

Index Scan using idx_name on task  (cost=0.28..142102.57 rows=3470 width=34) (actual time=14.690..22.894 rows=4436 loops=1)
"  Index Cond: ((situation = ANY ('{0,1,2,3,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}'::integer[])) AND (deadline < CURRENT_TIMESTAMP))"
Planning Time: 1.335 ms
JIT:
 Functions: 5
 Options: Inlining false, Optimization false, Expressions true, Deforming true
 Timing: Generation 1.654 ms, Inlining 0.000 ms, Optimization 1.214 ms, Emission 13.163 ms, Total 16.030 ms
Execution Time: 24.758 ms

這種成本水平是否可以接受,或者該指數是否需要改進?

指數:

CREATE INDEX idx_name ON task (situation, deadline, approved)
WHERE
deadline IS NOT NULL AND
situation <> ALL ('{4,5}'::integer[]) AND
approved = 'N';

我的查詢:

SELECT
       task.deadline,
       task.id
   FROM
       task
   WHERE
       task.deadline IS NOT NULL
       AND task.situation IN ('0', '1', '2', '3', '6' ,'7' ,'8','9','10','11','12','13','14','15','16','17','18','19','20')
       AND task.situation NOT IN ('4', '5')
       AND task.deadline < CURRENT_TIMESTAMP
       AND task.approved = 'N';

索引好,查詢快。

但是索引可以更好,查詢更快。索引列approved只是帶有條件的死運費approved = 'N'。去掉它。

CREATE INDEX idx_name ON task (situation, deadline)
WHERE  deadline IS NOT NULL
AND    situation <> ALL ('{4,5}'::integer[])
AND    approved = 'N';

索引大小很重要,即使approvedvarchar(1)(並且可能應該是boolean)。由於deadline是(對齊)timestampwith time zone)類型,添加的索引列approved每個索引元組至少浪費 8 個字節 - 使其增長 1/3。

更好的是,如果範例有SELECT deadline, id ...任何指示,則應該將其附加id為“包含”列以允許 僅索引掃描

CREATE INDEX idx_name ON task (situation, deadline) INCLUDE (id)
WHERE  deadline IS NOT NULL
AND    situation <> ALL ('{4,5}'::integer[])
AND    approved = 'N';

需要 Postgres 11 或更高版本。將大小恢復到以前的大小。

看:

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