【问题标题】:Postgresql not using created functional indexPostgresql 不使用创建的功能索引
【发布时间】:2020-03-23 13:08:56
【问题描述】:

为了运行查询,

SELECT count(*) FROM reservations WHERE 
(((json #>> '{details, attributes, checkIn}')::timestamptz at time zone (json #>> '{details, attributes, destinationTimeZone}'))) >= '2019-01-17' AND (((json #>> '{details, attributes, checkIn}')::timestamptz at time zone (json #>> '{details, attributes, destinationTimeZone}'))) < '2020-04-01';

我创建了功能索引:

CREATE FUNCTION text2tstz(text) RETURNS timestamp with time zone
   LANGUAGE sql IMMUTABLE AS
$$SELECT CASE WHEN $1 ~ '^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z?$'
            THEN CAST($1 AS timestamp with time zone)
       END$$;


 CREATE INDEX CONCURRENTLY checkIn_index ON reservations 
((text2tstz(json ->> '{details,attributes,checkIn}')at time zone (json ->> '{details, attributes, destinationTimeZone}')));

索引已成功创建,但是当我进行 EXPLAIN ANALYZE 时,我没有发现我的索引正在被使用,谁能帮我解决我的错误?

explain analyze SELECT count(*) FROM reservations WHERE 
((text2tstz(json #>> '{details, attributes, checkIn}') at time zone (json #>> '{details, attributes, destinationTimeZone}'))) >= '2019-01-17' AND ((text2tstz(json #>> '{details, attributes, checkIn}') at time zone (json #>> '{details, attributes, destinationTimeZone}'))) < '2020-04-01';

解释分析结果

Aggregate  (cost=120515.80..120515.81 rows=1 width=0) (actual time=13794.176..13794.176 rows=1 loops=1)
  ->  Seq Scan on reservations  (cost=0.00..120510.32 rows=2193 width=0) (actual time=9479.960..13792.877 rows=2973 loops=1)
        Filter: ((timezone((json #>> '{details,attributes,destinationTimeZone}'::text[]), ((json #>> '{details,attributes,checkIn}'::text[]))::timestamp with time zone) >= '2019-01-17 00:00:00'::timestamp without time zone) AND (timezone((json #>> '{details,attributes,destinationTimeZone}'::text[]), ((json #>> '{details,attributes,checkIn}'::text[]))::timestamp with time zone) < '2020-04-01 00:00:00'::timestamp without time zone))
        Rows Removed by Filter: 435536
Planning time: 0.246 ms
Execution time: 13794.257 ms

我使用的是 Postgresql 9.4.8

【问题讨论】:

  • 在索引创建中使用 #>> 运算符而不是 ->> 并查看它是如何工作的。这是不正确的。但是不能保证 postgres 会使用索引,因为读取整个表可能会更好,因为它只有很少的记录。
  • @BjarniRagnarsson Thanyou 但 #>> 没有帮助。还是一样。

标签: postgresql indexing postgresql-9.4 functional-index


【解决方案1】:

你应该像这样定义你的不可变函数:

CREATE FUNCTION get_checkin(jsonb) RETURNS timestamp with time zone
   LANGUAGE sql IMMUTABLE AS
$$SELECT ($1 #>> '{details, attributes, checkIn}')::timestamptz)
AT TIME ZONE
($1 #>> '{details, attributes, destinationTimeZone}')$$;

然后你可以在索引中使用该函数:

CREATE INDEX ON reservations (get_checkin(json));

别忘了收集统计数据:

ANALYZE reservations;

然后像这样查询:

SELECT count(*)
FROM reservations
WHERE get_checkin(json) >= '2019-01-17'
  AND get_checkin(json) < '2020-04-01';

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-15
    相关资源
    最近更新 更多