标签: postgresql-performance

提高 PostgreSQL 数据仓库 (RDS) 中的更新性能

我正在使用 Amazon RDS 上托管的 Postgres 数据仓库。当尝试从同一数据库中的另一个表更新事实表的一列(2500 万行)时,查询需要几天时间才能运行。为什么会发生这种情况,我该如何提高这种性能?我知道 PG 是为 OLTP 而设计的,而不是 OLAP,但是在这个表上选择查询性能通常相当不错。

有问题的查询如下所示:

UPDATE a
SET a.value = b.value
FROM b
WHERE a.id = b.id
Run Code Online (Sandbox Code Playgroud)

b是不同架构中的临时表,但与a. 两个表在 上都有主键idvalue列上没有索引或约束。有依赖于表a但没有外键的视图

我在 RDS 上使用 PG 9.5。具有 256 GB 存储空间的通用型 (SSD),因此在用尽我们最初的突发 IOPS 后,我的 IOPS 应该会略低于 800。

IOPS 节流真的是这里的问题吗?在观看查询运行时,我看到写入性能约为 400 IOPS,读取性能类似。25,000,000 行 / 400 IOPS = 17 小时,但此查询的运行时间比 24 小时长得多(大约 30 小时后取消以尝试进行调整)。同一个表上还有其他一些定期更新流量,但是当我看到这个查询花费了多长时间时,我在大约 20 小时时停止了它。

我想知道我的一般更新方法是否错误,或者是否有使用 postgres 操作数据仓库(OLAP 工作负载)的一般建议。我能否通过放弃 RDS 并在 EC2 上运行 PG 来获得更好的性能?

更新:受回复和评论的启发,我对 45k …

postgresql performance data-warehouse update amazon-rds postgresql-performance

5
推荐指数
1
解决办法
2968
查看次数

PostgreSQL - 多列 B 树索引如何处理第一列的 order by 和第二列的 IN 查找?

我创建了这样的表(类似于http://use-the-index-luke.com/sql/example-schema/postgresql/performance-testing-scalability 中的示例)

CREATE TABLE scale_data (
   section NUMERIC NOT NULL,
   id1     NUMERIC NOT NULL, -- unique values simulating ID or Timestamp
   id2     NUMERIC NOT NULL -- a kind of Type
);
Run Code Online (Sandbox Code Playgroud)

填充它:

INSERT INTO scale_data
SELECT sections.sections, sections.sections*10000 + gen.gen
     , CEIL(RANDOM()*100) 
  FROM GENERATE_SERIES(1, 300)     sections,
       GENERATE_SERIES(1, 90000) gen
 WHERE gen <= sections * 300;
Run Code Online (Sandbox Code Playgroud)

它生成了 13545000 条记录。

综合指数就可以了:

CREATE INDEX id1_id2_idx
  ON public.scale_data
  USING btree
  (id1, id2);
Run Code Online (Sandbox Code Playgroud)

并选择#1:

select id2 from scale_data 
where id2 in (50)
order …
Run Code Online (Sandbox Code Playgroud)

postgresql performance index postgresql-9.5 postgresql-performance

5
推荐指数
1
解决办法
396
查看次数

与单列上的排序相比,两列上的排序非常慢

我正在使用 Postgres,我看到在两列上使用 order by 时,与仅在列上使用 order by 相比,我的查询慢了几个数量级。我在考虑的表中有大约 2950 万行。

以下是三个不同查询的结果:

仅按 id 排序:

EXPLAIN ANALYZE SELECT "api_meterdata"."id", "api_meterdata"."meter_id", "api_meterdata"."datetime", "api_meter"."id" FROM "api_meterdata" INNER JOIN "api_meter" ON ( "api_meterdata"."meter_id" = "api_meter"."id" ) ORDER BY "api_meterdata"."id" DESC LIMIT 100;
                                                                               QUERY PLAN                                                            

------------------------------------------------------------------------------------------------------------------------------------------------------------------------  
 Limit  (cost=0.44..321.49 rows=100 width=20) (actual time=0.407..30.424 rows=100 loops=1)    
   ->  Nested Loop  (cost=0.44..94824299.30 rows=29535145 width=20) (actual time=0.402..30.090 rows=100 loops=1)
         Join Filter: (api_meterdata.meter_id = api_meter.id)
         Rows Removed by Join Filter: 8147
         ->  Index Scan Backward using api_meterdata_pkey on api_meterdata  (cost=0.44..58053041.74 rows=29535145 …
Run Code Online (Sandbox Code Playgroud)

postgresql performance postgresql-performance

5
推荐指数
1
解决办法
1636
查看次数

编写此查询的更好方法是什么?

我的数据库(Postgresql 10)具有以下架构:

CREATE TABLE "PulledTexts" (
"Id" serial PRIMARY KEY,
"BaseText" TEXT,
"CleanText" TEXT
);

CREATE TABLE "UniqueWords" (
"Id" serial PRIMARY KEY,
"WordText" TEXT
);

CREATE TABLE "WordTexts" (
"Id" serial PRIMARY KEY,
"TextIdId" INTEGER REFERENCES "PulledTexts",
"WordIdId" INTEGER REFERENCES "UniqueWords"
);
CREATE INDEX "IX_WordTexts_TextIdId" ON "WordTexts" ("TextIdId");
CREATE INDEX "IX_WordTexts_WordIdId" ON "WordTexts" ("WordIdId");
Run Code Online (Sandbox Code Playgroud)

一些示例数据:

INSERT INTO public."PulledTexts" ("Id", "BaseText", "CleanText") VALUES
(1, 'automate business audit', null),
(2, 'audit trial', null),
(3, 'trial', null),
(4, 'audit', null),
(5, 'fresh …
Run Code Online (Sandbox Code Playgroud)

postgresql performance subquery relational-division postgresql-performance

5
推荐指数
1
解决办法
211
查看次数

PostgreSQL 从 9.3 升级到 9.4 后非常慢

我们最近将一个 Amazon RDS 实例从 PostgreSQL 9.3 升级到 9.4。升级过程中没有出现问题,之后我们就跑了VACUUM ANALYZE。性能现在非常缓慢。下面是一个在 9.3 中花费几分之一秒的查询示例:

EXPLAIN ANALYZE SELECT room_name, id FROM common_activityinstance WHERE started_by_id = 1370408 AND room_name IN ('robcv28', 'foobartest', 'noroster', 'jscode', 'cv28', 'johansencouple', 'lv426', 'johansenfamily', 'johansen') AND end_time IS NULL;
                                                                              QUERY PLAN                                                                              
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on common_activityinstance  (cost=55.63..59.65 rows=1 width=13) (actual time=1.082..1.082 rows=0 loops=1)
   Recheck Cond: ((started_by_id = 1370408) AND (room_name = ANY ('{robcv28,foobartest,noroster,jscode,cv28,johansencouple,lv426,johansenfamily,johansen}'::text[])))
   Filter: (end_time IS NULL)
   Rows Removed by Filter: 925
   ->  BitmapAnd  (cost=55.63..55.63 rows=1 width=0) (actual …
Run Code Online (Sandbox Code Playgroud)

postgresql performance upgrade postgresql-9.3 postgresql-9.4 postgresql-performance

5
推荐指数
1
解决办法
1794
查看次数

ORDER BY 子句会降低查询性能

语境:

PostgreSQL 10,users表有3667438条记录,users表有一个名为social的JSONB,我们通常使用对计算函数输出进行索引的策略,这样我们就可以将信息聚合到一个单独的索引中。的输出engagement(social)函数是双精度数字类型。

问题:

有问题的条款是 ORDER BY engagement(social) DESC NULLS LAST,还有一个 btree 索引idx_in_social_engagement with DESC NULLS LAST附加到这个数据。

快速查询:

EXPLAIN ANALYZE
SELECT  "users".* FROM "users"
WHERE (follower_count(social) < 500000)
AND (engagement(social) > 0.03)
AND (engagement(social) < 0.25)
AND (peemv(social) < 533)
ORDER BY "users"."created_at" ASC
LIMIT 12 OFFSET 0;

Limit  (cost=0.43..52.25 rows=12 width=1333) (actual time=0.113..1.625 
rows=12 loops=1)
   ->  Index Scan using created_at_idx on users  (cost=0.43..7027711.55 rows=1627352 width=1333) (actual time=0.112..1.623 rows=12 loops=1)
         Filter: ((follower_count(social) < 500000) AND …
Run Code Online (Sandbox Code Playgroud)

postgresql performance order-by postgresql-10 postgresql-performance

5
推荐指数
1
解决办法
8670
查看次数

Postgres 性能测试、缓存和刷新

我一直在对各种 postgres SQL 查询进行一些测试。

测试通常涉及更改查询的语法、更改表连接或偶尔完全重写查询。

我注意到有时我会得到“明显”的大幅性能提升。我将运行一个查询,运行需要(比如)60 秒,我会做一个小改动,然后运行(比如)5 秒。

起初我认为这是因为我的小调整提高了性能。我已经意识到实际上必须有一些缓存正在进行,(要看到这一点,请尝试运行 60 秒的查询,然后几秒钟后再次运行它 - 它总是第二次运行得更快),我假设这个是因为数据已经在本地缓存在某处,所以当数据需要第二次读取时,它已经到手了。

我确信这是一个有用的性能特性,但它确实使得在调整查询时很难发现真正的性能改进。是否可以在每次执行之前刷新缓存以确保每个测试从同一位置开始?

谢谢

postgresql performance postgresql-performance

5
推荐指数
1
解决办法
4730
查看次数

Postgres JOIN 奇怪的行为

我刚刚开始学习 Postgres,我遇到的情况是,根据我在表上执行 JOIN 的方式,性能和计划输出似乎真的很奇怪。

这些是与其索引一起使用的表:

create table escola
(
    pk_codigo integer not null
        constraint pk_escola
            primary key,
    nome varchar(100),
    municipio varchar(150),
    uf char(2),
    cod_municipio integer,
    uf_id integer default 0 not null
        constraint fk_escola_uf_id
            references tb_uf
)
;

create index idx_escola_uf
    on escola (uf)
;

create index idx_escola_uf_id
    on escola (uf_id)
;

create index idx_multi_escola_uf_pk
    on escola (uf, pk_codigo)
;

create table if not exists candidato
(
    pk_numero_inscricao bigint not null
        constraint candidato_pk
            primary key,
    cod_municipio_residencia integer,
    municipio_residencia varchar(150),
    uf_residencia char(2), …
Run Code Online (Sandbox Code Playgroud)

postgresql performance index join postgresql-performance

5
推荐指数
1
解决办法
221
查看次数

带有 SELECT 的 SQL 函数与带有 RETURN QUERY SELECT 的 PLPGSQL 函数?

执行 SQL 查询的普通 SQL 函数之间是否有区别:

create function get_sports() returns setof sport as
$body$
    select * from sport;
$body$
language sql stable;
Run Code Online (Sandbox Code Playgroud)

和 PLPGSQL 函数返回相同的 SQL 查询:

create function get_sports() returns setof sport as
$body$
begin
    return query select * from sport;
end
$body$
language plpgsql stable;
Run Code Online (Sandbox Code Playgroud)

关于性能?在什么情况下应该使用哪个版本?

如果我们传递参数,那会改变什么吗?如:

create function get_sports(status int) returns setof sport as
$body$
    select * from sport where status = $1;
$body$
language sql stable;

create function get_sports(status int) returns setof sport as
$body$
begin
    return …
Run Code Online (Sandbox Code Playgroud)

postgresql performance plpgsql functions postgresql-performance

5
推荐指数
1
解决办法
1915
查看次数

PostgreSQL UDF(用户定义函数)开销

免责声明

这项任务可能看起来很深奥,但我还是想创建某种 POC。

目标

我的目标是让 PostgreSQL 数据库(版本 10)向使用它的应用程序公开一个 API。

API 需要采用一组 UDF 的形式:所有函数都属于一个公共方案,这是应用程序唯一可以访问的。桌子和其他东西隐藏在私人计划中。几乎就像,您知道的,面向对象的数据库
这就是我试图让它发挥作用的原因:

  • 它将数据库与应用程序分离,因此您可以重构/优化/非规范化前者,而破坏后者的风险较小。您甚至可以将其维护委托给另一个团队或部门(哦,天哪)
  • API 将服务的要求形式化。数据库当然是一种服务,但称为迁移的传统机制并不能很好地用于弄清楚其中发生了什么。想想多年来收集的成百上千的迁移,其中一些已经损坏,再也不会工作了,并且

好吧,没关系。

问题

因此,当我尝试创建一些非常简单的函数(例如从表中获取所有记录)时,我提到它们总是比它包装的查询慢。虽然这本身是完全可以接受和理解的,但时间差异可能很大。因此,无法接受。

这个例子

我有一张这样的桌子。

CREATE TABLE notifications (
    id SERIAL PRIMARY KEY,
    source_type INTEGER NOT NULL,
    content JSONB,
    created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP(3)
)
Run Code Online (Sandbox Code Playgroud)

并且其中有 >120k 条记录。
想象一下,我们想要获得所有这些。
在这里,我们通过一个简单的查询来完成。没有索引,JSONB 数据几乎每条记录 1kb。

EXPLAIN (ANALYZE,VERBOSE,BUFFERS) SELECT * FROM private.notifications;
                                                         QUERY PLAN                                                              
-------------------------------------------------------------------------------------------------------------------------------------
Seq Scan on private.notifications  (cost=0.00..16216.13 rows=120113 width=877) (actual time=0.015..496.473 rows=120113 loops=1)
  Output: id, source_type, content, created
  Buffers: …
Run Code Online (Sandbox Code Playgroud)

postgresql performance plpgsql functions postgresql-performance

5
推荐指数
1
解决办法
940
查看次数