基于这个职位的解决方案,我创建了以下部分索引:
CREATE INDEX CONCURRENTLY IF NOT EXISTS cdbus_message_message_vessel_barcode_delete_procedure_idx ON tare_new.cdbus_message USING btree
(
(vessel_barcode::int8),
(
length(regexp_replace(vessel_barcode, '\D', '', 'g')) = length(vessel_barcode)
AND length(vessel_barcode) = 16
)
)
WHERE (
length(regexp_replace(vessel_barcode, '\D', '', 'g')) = length(vessel_barcode)
AND length(vessel_barcode) = 16
)
;我需要这样的索引从源表中删除旧数据,其中"vessel_barcode“列存储为文本。此表中不匹配索引条件的行(参见上文)不会传递到处理的下一阶段,然后将"vessel_barcode“列作为bigint存储。
根据上面提到的文章,我尝试使用以下查询访问这个部分索引(在此之前,我检查了索引创建是否真正完成):
WITH vb AS (
SELECT 1017535400101448 AS vessel_barcode_int8
)
SELECT
*
FROM tare_new.cdbus_message cm
INNER JOIN vb ON
vb.vessel_barcode_int8 = cm.vessel_barcode::bigint
WHERE
length(regexp_replace(vessel_barcode, '\D'::text, ''::text, 'g'::text)) = length(vessel_barcode)
AND length(vessel_barcode) = 16
;问题是,解释仍然显示顺序扫描:
Gather (cost=1000.00..148473103.29 rows=96 width=1340)
Workers Planned: 2
-> Parallel Seq Scan on cdbus_message cm (cost=0.00..148472093.69 rows=40 width=1340)
Filter: ((length(vessel_barcode) = 16) AND ('1017535400101448'::bigint = (vessel_barcode)::bigint) AND (length(regexp_replace(vessel_barcode, '\D'::text, ''::text, 'g'::text)) = 16))知道为什么这不管用吗?cdbus_message的大小为1.2T,因此这里应该使用索引。
谢谢你的帮忙!
发布于 2023-04-26 17:06:46
Postgresql 14似乎没有像优化查询谓词那样优化索引条件(参见上面的解释结果)。因此,将索引谓词更改为:
length(regexp_replace(vessel_barcode, '\D', '', 'g')) = 16
AND length(vessel_barcode) = 16https://dba.stackexchange.com/questions/326471
复制相似问题