标签: postgresql-performance

如何在 PostgreSQL 上保持高插入性能

我正在从事一个项目,该项目将测量文件中的数据解析到 Posgres 9.3.5 数据库中。

核心是一个表(按月分区),其中包含每个测量点的一行:

CREATE TABLE "tblReadings2013-10-01"
(
-- Inherited from table "tblReadings_master":  "sessionID" integer NOT NULL,
-- Inherited from table "tblReadings_master":  "fieldSerialID" integer NOT NULL,
-- Inherited from table "tblReadings_master":  "timeStamp" timestamp without time zone NOT NULL,
-- Inherited from table "tblReadings_master":  value double precision NOT NULL,
  CONSTRAINT "tblReadings2013-10-01_readingPK" PRIMARY KEY ("sessionID", "fieldSerialID", "timeStamp"),
  CONSTRAINT "tblReadings2013-10-01_fieldSerialFK" FOREIGN KEY ("fieldSerialID")
      REFERENCES "tblFields" ("fieldSerial") MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE RESTRICT,
  CONSTRAINT "tblReadings2013-10-01_sessionFK" FOREIGN KEY ("sessionID")
  REFERENCES "tblSessions" ("sessionID") …
Run Code Online (Sandbox Code Playgroud)

postgresql performance insert postgresql-performance

9
推荐指数
2
解决办法
2万
查看次数

优化一系列时间戳的查询(一列)

我正在通过 Heroku 使用 Postgres 9.3。

我有一个表,“交通”,有 100 万条记录,每天都有很多插入和更新。我需要在不同的时间范围内跨该表执行 SUM 运算,这些调用最多可能需要 40 秒,我很想听听有关如何改进它的建议。

我在这张桌子上有以下索引:

CREATE INDEX idx_traffic_partner_only ON traffic (dt_created) WHERE campaign_id IS NULL AND uuid_self <> uuid_partner;
Run Code Online (Sandbox Code Playgroud)

这是一个示例 SELECT 语句:

SELECT SUM("clicks") AS clicks, SUM("impressions") AS impressions
FROM "traffic"
WHERE "uuid_self" != "uuid_partner"
AND "campaign_id" is NULL
AND "dt_created" >= 'Sun, 29 Mar 2015 00:00:00 +0000'
AND "dt_created" <= 'Mon, 27 Apr 2015 23:59:59 +0000' 
Run Code Online (Sandbox Code Playgroud)

这是解释分析:

Aggregate  (cost=21625.91..21625.92 rows=1 width=16) (actual time=41804.754..41804.754 rows=1 loops=1)
  ->  Index Scan using idx_traffic_partner_only on …
Run Code Online (Sandbox Code Playgroud)

postgresql performance index optimization postgresql-9.3 postgresql-performance

9
推荐指数
1
解决办法
5849
查看次数

在有时很慢的大表上调试查询

我有一个由 Postgres 数据库支持的 Web API,性能通常非常好。我监控整个数据库和应用程序的性能。我的大部分查询(以及与此相关的 API 调用)都在不到 100 毫秒内完成,但偶尔会出现异常值。

就在今天,我收到一条警报,指出 API 调用耗时超过 5,000 毫秒,因此被看门狗终止。从挖掘日志开始,底层的 Postgres 查询花费了 13秒的时间来完成(一切都是异步的,所以即使 API 请求被终止,SQL 查询仍在继续)。

这是非常不典型的,即使当我手动运行有问题的查询时,我也无法重现这种糟糕的时间安排。它对我来说在 985 毫秒内完成(根据解释分析)。

我的问题

我不知道接下来还要看什么来尝试制定关于为什么会发生这种情况的理论。这种情况并不经常发生每天只有成千上万次类似事件发生一次或两次,但它确实经常发生,令人讨厌。我错过了什么?我应该下一步做什么来调试它?我不是来自 DBA 背景,所以这可能是一个愚蠢的问题。

一些快速背景和我尝试过的

这一切都托管在 Amazon 的 RDS 上,在 m3.xlarge 上运行 Postgres 9.4,预配置 IOPS (2,000)。

我的一个表,我们称之为“详细信息”相当大,包含近 500 万行,并且以每天 25,000 条记录的速度增长。这个表永远不会更新或删除,只是插入和选择,但代表了我的应用程序的“核心”——几乎所有感兴趣的东西都是从这个表中读取的。

在这个特定情况下,我知道这个查询有一些参数(例如底部的日期和 id),因此它正在查看一个相当大的数据集。我已经开发了这个查询的一个大大改进的版本,它将这个特定场景从 985 毫秒减少到 20 毫秒。但是,我担心这里还有其他“在起作用”的东西,一个查询需要不到一秒的时间来运行我,在生产中时不时需要超过 13 秒。

桌子

嗯,有点……它包含更多的列,但我删除了任何不在查询中或没有索引的列。以下查询中使用的所有列或附加索引的所有列都已保留;

CREATE TABLE "public"."details" (
    "value" numeric,
    "created_at" timestamp(6) WITH TIME ZONE NOT NULL,
    "updated_at" timestamp(6) WITH TIME ZONE NOT NULL,
    "effective_date" timestamp(6) …
Run Code Online (Sandbox Code Playgroud)

postgresql performance autovacuum amazon-rds postgresql-performance

9
推荐指数
1
解决办法
2922
查看次数

优化大表上的 LATERAL JOIN 查询

我正在使用 Postgres 9.5。我有一个记录来自多个网站的页面点击量的表格。该表包含从 2016 年 1 月 1 日到 2016 年 6 月 30 日的大约 3200 万行。

CREATE TABLE event_pg (
   timestamp_        timestamp without time zone NOT NULL,
   person_id         character(24),
   location_host     varchar(256),
   location_path     varchar(256),
   location_query    varchar(256),
   location_fragment varchar(256)
);
Run Code Online (Sandbox Code Playgroud)

我正在尝试调整一个查询,该查询计算执行给定页面命中序列的人数。该查询旨在回答诸如“有多少人查看了主页,然后访问了帮助站点,然后查看了感谢页面”之类的问题?结果看起来像这样

?????????????????????????????????????????
?  home-page ? help site  ? thankyou    ?
?????????????????????????????????????????
? 10000      ? 9800       ?1500         ?
?????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)

请注意数字正在减少,这是有道理的,因为查看主页的 10000 人 9800 继续访问了帮助站点,而其中 1500 人继续点击了感谢页面。

3 步序列的 SQL 使用横向连接,如下所示:

SELECT 
  sum(view_homepage) AS view_homepage,
  sum(use_help) AS use_help,
  sum(thank_you) AS thank_you
FROM ( …
Run Code Online (Sandbox Code Playgroud)

postgresql performance optimization greatest-n-per-group postgresql-performance

9
推荐指数
1
解决办法
8114
查看次数

多列索引和 OR 子句

我的message应用程序中有一个表,该表上最常执行的 SQL 查询之一如下:

select * from message message0_ 
 where message0_.sender_id=? or message0_.recipient_id=?
 order by message0_.send_date asc;
Run Code Online (Sandbox Code Playgroud)

我基本上是在查询当前用户已收到或发送的消息。

sender_id&的参数值recipient_id是当前用户 ID。

我创建了以下索引:

CREATE INDEX ON message(recipient_id, sender_id);
Run Code Online (Sandbox Code Playgroud)

我想知道字段的顺序是否对我的用例很重要,请记住我的 SQL 查询中的 OR 子句。

有人可以帮忙吗?

postgresql performance index postgresql-performance

9
推荐指数
1
解决办法
2902
查看次数

PostgreSQL - 处理数千个元素的数组

我希望根据列是否包含在作为整数数组传递的大值列表中来选择行。

这是我目前使用的查询:

SELECT item_id, other_stuff, ...
FROM (
    SELECT
        -- Partitioned row number as we only want N rows per id
        ROW_NUMBER() OVER (PARTITION BY item_id ORDER BY start_date) AS r,
        item_id, other_stuff, ...
    FROM mytable
    WHERE
        item_id = ANY ($1) -- Integer array
        AND end_date > $2
    ORDER BY item_id ASC, start_date ASC, allowed ASC
) x
WHERE x.r <= 12
Run Code Online (Sandbox Code Playgroud)

该表的结构如下:

    Column     |            Type             | Collation | Nullable | Default 
---------------+-----------------------------+-----------+----------+---------
 item_id       | integer                     |           | not null …
Run Code Online (Sandbox Code Playgroud)

postgresql performance postgresql-performance

9
推荐指数
1
解决办法
1812
查看次数

在全文搜索查询中优化 ORDER BY

我有一张大桌子,里面entities有大约 1500 万条记录。我想在他们的name.

我在 上有一个全文索引name,用于:gin_ix_entity_full_text_search_name

询问:

 SELECT "entities".*,
         ts_rank(to_tsvector('english', "entities"."name"::text),
         to_tsquery('english', 'hockey'::text)) AS "rank0.48661998202865475"
    FROM "entities" 
         WHERE "entities"."place" = 'f' 
              AND (to_tsvector('english', "entities"."name"::text) @@ to_tsquery('english', 'hockey'::text)) 
         ORDER BY "rank0.48661998202865475" DESC LIMIT 5
Run Code Online (Sandbox Code Playgroud)

持续时间 25,623 毫秒

解释计划
1 限制(成本=12666.89..12666.89 行=5 宽度=3116)
2 -> 排序(成本=12666.89..12670.18 行=6571 宽度=3116)
3 排序键: (ts_rank(to_tsvector('english'::regconfig, (name)::text), '''hockey'''::tsquery))
4 -> 实体上的位图堆扫描(成本 = 124.06..12645.06 行 = 6571 宽度 = 3116)
5 重新检查条件: (to_tsvector('english'::regconfig, (name)::text) @@'''hockey'''::tsquery)
6 过滤器:(不是地方)
7 -> gin_ix_entity_full_text_search_name 上的位图索引扫描(成本=0.00..123.74 行=6625 …

postgresql performance query full-text-search postgresql-performance

8
推荐指数
3
解决办法
3891
查看次数

加速创建 Postgres 部分索引

我正在尝试为 Postgres 9.4 中的大型(1.2TB)静态表创建部分索引。

我的数据是完全静态的,所以我可以插入所有数据,然后创建所有索引。

在这个 1.2TB 的表中,我有一个名为的列run_id,可以清晰地划分数据。通过创建涵盖一系列run_ids 的索引,我们获得了出色的性能。下面是一个例子:

CREATE INDEX perception_run_frame_idx_run_266_thru_270
ON run.perception
(run_id, frame)
WHERE run_id >= 266 AND run_id <= 270;
Run Code Online (Sandbox Code Playgroud)

这些部分索引为我们提供了所需的查询速度。不幸的是,每个部分索引的创建大约需要 70 分钟。

看起来我们的 CPU 有限(top进程显示为 100%)。
我可以做些什么来加快部分索引的创建?

系统规格:

  • 18核至强
  • 192GB 内存
  • RAID 中的 12 个 SSD
  • 自动吸尘器关闭
  • 维护工作内存:64GB(太高?)

表规格:

  • 大小:1.26 TB
  • 行数:105.37亿
  • 典型的索引大小:3.2GB(有 ~.5GB 的差异)

表定义:

CREATE TABLE run.perception(
id bigint NOT NULL,
run_id bigint NOT NULL,
frame bigint NOT NULL,
by character varying(45) NOT NULL,
by_anyone bigint NOT …
Run Code Online (Sandbox Code Playgroud)

postgresql performance index ddl performance-tuning postgresql-performance

8
推荐指数
1
解决办法
3546
查看次数

仅具有索引存储的 Postgresql

我有一个带有(bigint) 和(double)的 PostgreSQL 表。该表有数百亿行。我在 ( key , value )上有一个 btree 用于按键辅助查找。该表永远不会更新。

我在这个表上执行的唯一查询是在上的相等谓词以获取相应的value,它利用了 B 树。

PostgreSQL 消耗的存储在这里很糟糕。它将OIDkeyvalue存储在表中,并将keyvalue存储在索引中。我本质上是将所有东西存储两次!

如何配置此表以节省空间?理想情况下,如何在 B 树中只存储一次元组。

postgresql performance postgresql-performance

8
推荐指数
1
解决办法
1050
查看次数

临时表上的索引使用情况

我有两个相当简单的查询。第一个查询

 UPDATE mp_physical SET periodic_number = '' WHERE periodic_number is NULL;
Run Code Online (Sandbox Code Playgroud)

这是计划

 duration: 0.125 ms  plan:
    Query Text: UPDATE mp_physical  SET periodic_number = '' WHERE periodic_number is NULL;
    Update on mp_physical  (cost=0.42..7.34 rows=1 width=801)
      ->  Index Scan using "_I_periodic_number" on mp_physical  (cost=0.42..7.34 rows=1 width=801)
            Index Cond: (periodic_number IS NULL)
Run Code Online (Sandbox Code Playgroud)

第二个:

 UPDATE observations_optical_temp SET designation = '' WHERE periodic_number is NULL;
Run Code Online (Sandbox Code Playgroud)

它的计划是:

duration: 2817.375 ms  plan:
    Query Text: UPDATE observations_optical_temp SET periodic_number = '' WHERE periodic_number is NULL;
    Update on observations_optical_temp …
Run Code Online (Sandbox Code Playgroud)

postgresql performance index execution-plan temporary-tables postgresql-performance

8
推荐指数
1
解决办法
1万
查看次数