Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql 优化Postgres时间戳查询范围_Postgresql_Indexing_Query Optimization_Database Partitioning_Postgresql Performance - Fatal编程技术网

Postgresql 优化Postgres时间戳查询范围

Postgresql 优化Postgres时间戳查询范围,postgresql,indexing,query-optimization,database-partitioning,postgresql-performance,Postgresql,Indexing,Query Optimization,Database Partitioning,Postgresql Performance,我定义了下表和索引: CREATE TABLE ticket ( wid bigint NOT NULL DEFAULT nextval('tickets_id_seq'::regclass), eid bigint, created timestamp with time zone NOT NULL DEFAULT now(), status integer NOT NULL DEFAULT 0, argsxml text, moduleid character var

我定义了下表和索引:

CREATE TABLE ticket
(
  wid bigint NOT NULL DEFAULT nextval('tickets_id_seq'::regclass),
  eid bigint,
  created timestamp with time zone NOT NULL DEFAULT now(),
  status integer NOT NULL DEFAULT 0,
  argsxml text,
  moduleid character varying(255),
  source_id bigint,
  file_type_id bigint,
  file_name character varying(255),
  status_reason character varying(255),
  ...
)
我在
created
时间戳上创建了一个索引,如下所示:

CREATE INDEX ticket_1_idx
  ON ticket
  USING btree
  (created );
这是我的问题

select * from ticket 
where created between '2012-12-19 00:00:00' and  '2012-12-20 00:00:00'
在唱片数量开始增长(约500万张)之前,这一切都运转良好,现在它要花很长时间才能恢复

解释分析揭示了这一点:

"Index Scan using ticket_1_idx on ticket  (cost=0.00..10202.64 rows=52543 width=1297) (actual time=0.109..125.704 rows=53340 loops=1)"
"  Index Cond: ((created >= '2012-12-19 00:00:00+00'::timestamp with time zone) AND (created <= '2012-12-20 00:00:00+00'::timestamp with time zone))"
"Total runtime: 175.853 ms"
也创造

create CLUSTER ticket USING ticket_1_idx;
什么都不管用。我做错了什么?为什么选择顺序扫描?索引应该使查询速度更快。可以做些什么来优化它

如果要使用
群集
,则显示的语法无效

使用ticket\u 1\u idx创建集群ticket

运行一次:

CLUSTER ticket USING ticket_1_idx;
这对更大的结果集有很大帮助。对于返回的一行,没有这么多。
Postgres会记住后续调用要使用的索引。如果您的表不是只读的,效果会随着时间的推移而恶化,您需要每隔一定的时间重新运行:

CLUSTER ticket;
可能只在易失性分区上。见下文

但是,如果有大量更新,
集群
(或
真空满
)实际上可能对性能有害。适当的膨胀量允许
UPDATE
将新行版本放在同一数据页上,并避免了在操作系统中过于频繁地物理扩展底层文件的需要。您可以使用经过仔细调整的
FILLFACTOR
来充分利用这两个方面:

CLUSTER
对表进行独占锁定,这在多用户环境中可能是个问题

当对表进行集群时,将获取一个
访问独占
锁 在上面。这将防止任何其他数据库操作(读取和 从对表的操作开始写入,直到
集群完成

我的。考虑:

集群
真空满负荷
不同,它可以在线工作,无需持有 处理期间对已处理表的独占锁定。pg_重新包装是 引导效率高,性能可与直接使用
集群
媲美

以及:

pg_repack需要在重组结束时获得独占锁

1.3.1版适用于:

PostgreSQL 8.3、8.4、9.0、9.1、9.2、9.3、9.4

版本1.4.2适用于:

PostgreSQL 9.1、9.2、9.3、9.4、9.5、9.6、10

查询 查询本身非常简单,不会导致任何性能问题

然而,一个关于正确性的词:构造包括边界。您的查询将选择12月19日的所有记录,以及12月20日00:00小时的记录。这是一个极不可能的要求。很可能,你真的想要:

SELECT *
FROM   ticket 
WHERE  created >= '2012-12-19 0:0'
AND    created <  '2012-12-20 0:0';
在新月份开始前创建一个新索引。您可以使用cron作业轻松地自动化任务。
可以选择
删除旧月份的部分索引

  • 除了
    集群
    (不能对部分索引进行操作)之外,还要保留总索引。如果旧记录从未更改,那么表分区将大大有助于完成此任务,因为您只需要重新对新分区进行集群。 同样,如果记录从未更改,您可能不需要使用
    集群

  • 如果将最后两个步骤结合起来,性能应该会非常出色

    性能基础 您可能缺少其中一个基本要素。所有通常的性能建议均适用于:


    它没有进行顺序扫描。它正在进行索引扫描,而且只需要175毫秒就可以运行。如果要花很长时间,OP可能有一个巨大的数据集,需要很长时间才能通过网络传输,而不是运行查询。\BTW:
    effective\u cache\u size=3
    可能有点太低了。(但在这种情况下可能不会伤害)为什么你考虑175MS“AGE”?不要做<代码>选择*<代码>,因为它会增加结果集的大小以转移到客户端。
    SELECT *
    FROM   ticket 
    WHERE  created >= '2012-12-19 0:0'
    AND    created <  '2012-12-20 0:0';
    
    CREATE INDEX ticket_created_idx ON ticket(created)
    WHERE created >= '2012-12-01 00:00:00'::timestamp;