标签: postgresql

Postgres 批量更新插入性能

我正在对一个包含 3000 万行的表进行批量 UPSERT。该表只有两列(varchar 作为主键和整数)。首先将输入数据导入到临时表中,然后执行批量更新插入(使用 INSERT ... ON CONFLICT DO UPDATE 语句)。批量大小为 4000。

我的问题是 - 您能给我哪些性能建议?当表较小时(5-1000万条记录),性能就足够好了。对于 3000 万行,这还不够好,单批 4000 条记录持续 2 到 30 秒。

当然,我几乎没有并行执行此导入的服务,因此我使用咨询锁来同步它们(一次仅执行一个批量更新插入)。我是否应该删除咨询锁以并行执行更新插入?然后我将不得不处理死锁(并使用较小的批量大小来减少死锁机会?)。

我可以采取哪些措施来提高批量更新插入的性能?

这是我的大表:

CREATE TABLE my_big_table (
  sender VARCHAR(30) PRIMARY KEY,
  count  INTEGER NOT NULL DEFAULT 0
)
WITH (
  fillfactor = 80,
  autovacuum_vacuum_scale_factor = 0,
  autovacuum_vacuum_threshold = 40000
);
Run Code Online (Sandbox Code Playgroud)

这是 UPSERT 查询:

INSERT INTO my_big_table AS MBT (sender, count)
    SELECT destination, count(*) as received_count
    FROM my_temp_table
    GROUP BY destination
ON CONFLICT (sender) DO UPDATE
    SET …
Run Code Online (Sandbox Code Playgroud)

postgresql performance update upsert postgresql-performance

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

PostgreSQL 11:如何对 1000 个租户进行分区

设置

我们有一个多租户应用程序,大约有 1000 个客户。当客户流失时,我们会在一段时间后删除他们的所有数据。我们有一些非常大的表,我们正在考虑使用分区来按客户拆分它们。

问题

1000 个租户(客户)是很多分区 - 在 PostgreSQL 上这样做合理吗?

更多细节

目前,我们的租户之间的分离是通过account_id数据库中所有表上的列来实现的。有几张桌子都很大。例如,有一个event表(我对分区感兴趣的表)包含审核日志和我们应用程序中发生的所有事件的其他事件。

以下是有关事件表的一些事实:

  • 它包含大约 300M 行+一些复合/部分索引。
  • 事件计数account_id非常不均匀,5% 的帐户拥有 50% 的数据。
  • 有一个时间戳字段和其他一些字段(JSONB,author_id等等)
  • 写操作:主要插入和删除(每account_id)。删除的数据可能有数百万行。没有更新。删除大帐户的情况很少见,目前并不是一个大的性能问题。
  • 选择特定事件(通过account_id+ id)或给定时间段内的所有事件。并不总是设定时间段。account_id始终出现在查询中。

可能的解决方案

分区方式account_id

优点:

  • 删除速度会很快,因为DROP TABLE.
  • 查询也应该相当不错,因为所有查询都包含WHERE account_id = 123

缺点:

  • 1000 个分区对于 Postgres 来说太多了吗?
  • 每个帐户的事件分布不均匀,创建了一些超大分区和一些小分区。

按时间戳分区:

优点:

  • 最近的数据通常会被访问,并且会使带有时间戳的查询更快。
  • 事件的分布更加可预测/均匀。

缺点:

  • 删除单个帐户可能会触及很多分区 - 这不是一个大问题。
  • 始终需要包含按时间戳的过滤器 - 这并不总是可能的。

postgresql partitioning

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

所有记录中数组列类型的唯一性

这里有张桌子

id serial primary key,
names varchar(20)[]
Run Code Online (Sandbox Code Playgroud)

它包含这样的记录

1, {"one", "two", "three"}
Run Code Online (Sandbox Code Playgroud)

然后,插入下一条记录(注意one数组元素已存在于现有记录中)

2, {"four", "one"}
Run Code Online (Sandbox Code Playgroud)

或者通过向数组添加一个元素来更新现有记录,但此类字符串元素已在其他记录中使用。

是否可以创建一个唯一的约束,不允许在所有行中全局重复数组内的元素,而不仅仅是在数组值本身内?

postgresql array

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

PostgreSQL 中的递归查询性能不佳

我在 PosgreSQL 中的递归查询性能很差。

psql --version
psql (PostgreSQL) 10.7 (Ubuntu 10.7-1.pgdg16.04+1)
Run Code Online (Sandbox Code Playgroud)

这个想法是拥有树状的评论结构。所以什么时候parent_idNULL父评论,什么时候是整数,什么时候是回复。

我的评论表()的表结构如下\d+ comment

     Column      |           Type           | Collation | Nullable |               Default               | Storage  | Stats target | Description 
-----------------+--------------------------+-----------+----------+-------------------------------------+----------+--------------+-------------
 id              | bigint                   |           | not null | nextval('comment_id_seq'::regclass) | plain    |              | 
 website_page_id | bigint                   |           | not null |                                     | plain    |              | 
 author_id       | bigint                   |           | not null |                                     | plain    |              | 
 parent_id       | bigint                   |           |          |                                     | …
Run Code Online (Sandbox Code Playgroud)

postgresql performance postgresql-performance

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

如何区分 pg_type 中的独立复合类型和表复合类型?

查询时pg_type,我感兴趣的是识别独立的复合类型(用户定义的),而不是与表一起创建的复合类型。也许有一种查找方法pg_class(使用typrelid)可能会有所帮助,但目前尚不清楚我如何做到这一点。

postgresql

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

什么时候需要AS关键字?

在以下语句中(PostgreSQL 11):

=> SELECT c cost FROM tt;
ERROR:  syntax error at or near "cost"
LINE 1: SELECT c cost FROM tt;
Run Code Online (Sandbox Code Playgroud)

我收到一个错误。在字段表达式周围添加括号没有帮助 ( SELECT (c) cost FROM tt;)。但添加AS关键字就可以解决这个问题。

=> SELECT c AS cost FROM tt;
 cost 
------
    1
...
Run Code Online (Sandbox Code Playgroud)

我意识到这cost是一个关键字,但我的印象是该AS关键字是可选的。

从语言的角度来看,为什么AS这里需要(或有帮助)关键字?这里的 PostgreSQL 行为是标准的还是在某处记录的?

还有其他情况AS需要使用关键字吗?

postgresql sql-standard

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

Postgres 日志表

postgres中是否有包含日志文件信息的表?我希望创建 postgres 日志中信息的视图/报告。我想做这样的事情:

SELECT *
FROM log_table;
Run Code Online (Sandbox Code Playgroud)

postgresql

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

如何在 PostgreSQL 中使用 aes-256-gcm 加密来加密列?

作为数据库点人员,我需要对表中任何位置的 SSN 号码进行加密。我们使用 PostgreSQL。我的应用程序同行要求我们使用 AES-256-GCM 加密算法。但是,我不太确定如何在 postgresql 中应用它。

经过谷歌搜索后,我可以使用这两种 AES 方法之一进行加密:

1.

UPDATE ssnTable
   SET encrypted_ssn = encrypt(encrypted_ssn::bytea, 'mykey', 'aes')`
Run Code Online (Sandbox Code Playgroud)

2.

UPDATE ssnTable
   SET encrypted_ssn = pgp_sym_encrypt(encrypted_ssn, 'mykey', 'compress-algo=1, cipher-algo=aes256')
Run Code Online (Sandbox Code Playgroud)

以上都没有专门使用“aes-256-gcm”算法,这正是我被要求使用的算法。关于如何在 PostgreSQL 的列上使用这个算法有什么想法吗?

postgresql encryption

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

打破 Postgres 11 中的递归查询

我在从树结构中获取正确的数据时遇到了一些麻烦,我只希望分支匹配条件中的第一个节点成为查询的结果。

我有这个域表:

create table domains(
    id bigint,
    domain_name varchar,
    parent_id bigint,
    valid boolean
)

insert into domains values
    (1, 'example.com', null, false),
    (2, 'a.example.com', 1, true),
    (3, 'b.example.com', 1, false),
    (4, 'c.b.example.com', 3, true),
    (5, 'd.a.example.com', 2, true)
Run Code Online (Sandbox Code Playgroud)

这给出了这棵树,其中有效域为绿色:

域图

基于此,我希望a.example.comc.b.example.com作为有效域返回。如果顶级域名example.com有效,则仅应返回该顶级域名。(“有效”只是其他地方确定的标志。)

我有一个递归查询来获取整个域树:

WITH RECURSIVE valid_domains AS (
  SELECT id, domain_name, valid FROM domains
  WHERE parent_id IS NULL

  UNION ALL

  SELECT d.id, d.domain_name, d.valid FROM domains d
  JOIN valid_domains vd ON d.parent_id = vd.id
)
SELECT …
Run Code Online (Sandbox Code Playgroud)

postgresql postgresql-11

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

Postgres 列级安全性

我在数据库testdb中有一个模式Snow。我正在努力为我的用户实现列级安全性。我的用户是老板经理实习生我以超级用户me的身份设置了该表的所有内容。他们都在集团公司

我的表是这样的:snow.company_table

 property_id |     property_address     |     city     | zip_code | state
-------------+--------------------------+--------------+----------+-------
           1 | 2564 Wescam Court        | Reno         |    89511 | NV    
           2 | 1732 Rubaiyat Road       | Grand Rapids |    49603 | MI    
           3 | 4094 Francis Mine        | Standish     |    96128 | CA    
           4 | 3193 Ashton Lane         | Briggs       |    78608 | TX    
           5 | 1519 North Street        | Alamosa      |    81102 …
Run Code Online (Sandbox Code Playgroud)

postgresql security postgresql-11

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