我正在对一个包含 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) 设置
我们有一个多租户应用程序,大约有 1000 个客户。当客户流失时,我们会在一段时间后删除他们的所有数据。我们有一些非常大的表,我们正在考虑使用分区来按客户拆分它们。
问题
1000 个租户(客户)是很多分区 - 在 PostgreSQL 上这样做合理吗?
更多细节
目前,我们的租户之间的分离是通过account_id数据库中所有表上的列来实现的。有几张桌子都很大。例如,有一个event表(我对分区感兴趣的表)包含审核日志和我们应用程序中发生的所有事件的其他事件。
以下是有关事件表的一些事实:
account_id非常不均匀,5% 的帐户拥有 50% 的数据。author_id等等)account_id)。删除的数据可能有数百万行。没有更新。删除大帐户的情况很少见,目前并不是一个大的性能问题。account_id+ id)或给定时间段内的所有事件。并不总是设定时间段。account_id始终出现在查询中。可能的解决方案
分区方式account_id:
优点:
DROP TABLE.WHERE account_id = 123缺点:
按时间戳分区:
优点:
缺点:
这里有张桌子
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)
或者通过向数组添加一个元素来更新现有记录,但此类字符串元素已在其他记录中使用。
是否可以创建一个唯一的约束,不允许在所有行中全局重复数组内的元素,而不仅仅是在数组值本身内?
我在 PosgreSQL 中的递归查询性能很差。
psql --version
psql (PostgreSQL) 10.7 (Ubuntu 10.7-1.pgdg16.04+1)
Run Code Online (Sandbox Code Playgroud)
这个想法是拥有树状的评论结构。所以什么时候parent_id是NULL父评论,什么时候是整数,什么时候是回复。
我的评论表()的表结构如下\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) 查询时pg_type,我感兴趣的是识别独立的复合类型(用户定义的),而不是与表一起创建的复合类型。也许有一种查找方法pg_class(使用typrelid)可能会有所帮助,但目前尚不清楚我如何做到这一点。
在以下语句中(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需要使用关键字吗?
postgres中是否有包含日志文件信息的表?我希望创建 postgres 日志中信息的视图/报告。我想做这样的事情:
SELECT *
FROM log_table;
Run Code Online (Sandbox Code Playgroud) 作为数据库点人员,我需要对表中任何位置的 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 的列上使用这个算法有什么想法吗?
我在从树结构中获取正确的数据时遇到了一些麻烦,我只希望分支匹配条件中的第一个节点成为查询的结果。
我有这个域表:
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.com和c.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) 我在数据库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 ×10
performance ×2
array ×1
encryption ×1
partitioning ×1
security ×1
sql-standard ×1
update ×1
upsert ×1