栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

优化大型表最近行查询的性能

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

优化大型表最近行查询的性能

一个 部分,多列索引

(person_id, created)
与伪
IMMUTABLE
状态将有助于(很多)。需要不时地重新创建以保持性能。

注意,如果表不是很大,则可以在很大程度上简化和使用普通的多列索引。
或者考虑在Postgres
12或更高版本(功能最终成熟的地方)中进行表分区。

一个原始 函数 提供了一个恒定的时间点,即3天或更早的时间(在您的情况下以unix纪元表示):

CREATE OR REPLACe FUNCTION f_orders_idx_start()  RETURNS int LANGUAGE sql IMMUTABLE PARALLEL SAFE COST 1 AS'SELECT 1387497600';

PARALLEL SAFE
仅适用于Postgres 10或更高版本。
1387497600
由于以下原因:

SELECT extract(epoch from now())::integer - 259200;-- 259200 being the result of 60 * 60 * 24 * 3

部分索引 基于此伪

IMMUTABLE
条件:

CREATE INDEX orders_created_recent_idx ON orders (person_id, created)WHERe created >= f_orders_idx_start();

基地您的 查询 在相同的条件:

SELECt *FROM   ordersWHERe  person_id = 1AND    created >= f_orders_idx_start()  -- match partial idx conditionAND    created >= extract(epoch from now())::integer - 259200;  -- actual condition

该行

AND created >= f_orders_idx_start()
似乎是多余的,但有助于说服Postgres使用部分索引。

一个 函数来重建功能和指标 不时。可能每天晚上都做一次正式工作:

CREATE OR REPLACe FUNCTION f_orders_reindex_partial()  RETURNS void AS$func$DECLARE   -- 3 days back, starting at 00:00   _start int := extract(epoch from now()::date -3)::int;BEGIN          IF _start = f_orders_idx_start() THEN      -- do nothing, nothing changes.   ELSE      DROP INDEX IF EXISTS orders_created_recent_idx;      -- Recreate IMMUTABLE function      EXECUTE format('         CREATE OR REPLACE FUNCTION f_orders_idx_start()RETURNS int LANGUAGE sql IMMUTABLE PARALLEL SAFE COST 1 AS         $$SELECT %s $$'       , _start      );      -- Recreate partial index      CREATE INDEX orders_created_recent_idx ON orders (person_id, created)      WHERe created >= f_orders_idx_start();   END IF;    END$func$  LANGUAGE plpgsql;

然后,要重新建立索引,请调用(最好是很少或没有并发负载):

SELECT f_orders_reindex_partial();  -- that's all

如果由于并发负载而无法删除和重新创建索引,请考虑

REINDEX CONCURRENTLY
使用Postgres 12或更高版本。简直太简单了:

REINDEX INDEX orders_created_recent_idx;

即使您从未调用此函数,所有查询仍将继续工作。 随着部分索引的增加,性能会随着时间的推移而缓慢下降。

我已经成功地将这种机制与几个大型表和类似的需求结合使用了。 非常快。

对于Postgres 9.2或更高版本,并且如果您的表只有很少的小列,并且该表的写入量不大,则可能需要花一个
覆盖索引

CREATE INDEX orders_created_recent_idx ON orders (person_id, created **, id** )WHERe created >= f_orders_idx_start();

在Postgres
11或更高版本中,您可能要使用

INCLUDE

CREATE INDEX orders_created_recent_idx ON orders (person_id, created) **INCLUDE (id)**WHERe created >= f_orders_idx_start();


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/420077.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号