PostgreSQL 使用默认值,加上
default_statistics_target=1000
random_page_cost=1.5
Run Code Online (Sandbox Code Playgroud)
版本
PostgreSQL 10.4 on x86_64-pc-linux-musl, compiled by gcc (Alpine 6.4.0) 6.4.0, 64-bit
Run Code Online (Sandbox Code Playgroud)
我已经抽真空并分析过。查询非常简单:
SELECT r.price
FROM account_payer ap
JOIN account_contract ac ON ap.id = ac.account_payer_id
JOIN account_schedule "as" ON ac.id = "as".account_contract_id
JOIN schedule s ON "as".id = s.account_schedule_id
JOIN rate r ON s.id = r.schedule_id
WHERE ap.account_id = 8
Run Code Online (Sandbox Code Playgroud)
每id列都是主键,所有被连接的都是外键关系,每个外键都有一个索引。加上一个索引account_payer.account_id。
返回 76k 行需要 3.93s。
Merge Join (cost=8.06..83114.08 rows=3458267 width=6) (actual time=0.228..3920.472 rows=75548 loops=1)
Merge Cond: (s.account_schedule_id = "as".id)
-> Nested Loop …Run Code Online (Sandbox Code Playgroud) 我的理解是更新锁定一个元组,将其标记为已删除,然后添加一个新元组。
换句话说,更新 = 删除 + 插入。
或者我曾经相信。但在 MVCC 中,更新与删除 + 插入之间似乎存在一些根本不同。
设置:
CREATE TABLE example (a int PRIMARY KEY, b int);
INSERT INTO example VALUES (1, 1);
Run Code Online (Sandbox Code Playgroud)
方法一:更新
CREATE TABLE example (a int PRIMARY KEY, b int);
INSERT INTO example VALUES (1, 1);
Run Code Online (Sandbox Code Playgroud)
方法二:删除插入
-- session A session B
BEGIN;
UPDATE example SET b = 2 WHERE a = 1;
DELETE FROM example WHERE a = 1;
COMMIT;
-- now there are 0 rows in table example (1 row was …Run Code Online (Sandbox Code Playgroud) 在 PostgreSQL 中,我一直在使用类似的语法
TABLE example1
UNION ALL
TABLE example2
Run Code Online (Sandbox Code Playgroud)
我理解这相当于
SELECT * FROM example1
UNION ALL
SELECT * FROM example2
Run Code Online (Sandbox Code Playgroud)
但是一位同事问了我这个问题,我找不到任何关于这个语法的 PostgreSQL 文档。(“TABLE”不是一个有用的搜索短语。)我在哪里可以找到有关它的文档?
它是 ANSI SQL 标准吗?
编辑:它目前显然甚至混淆了 StackExchanges 的语法突出显示。
CREATE TABLE widget (
id serial PRIMARY KEY,
name text NOT NULL,
ordinal int NOT NULL UNIQUE
);
Run Code Online (Sandbox Code Playgroud)
我有数据
id | name | ordinal
----+------+---------
1 | A | 1
2 | B | 2
3 | C | 3
Run Code Online (Sandbox Code Playgroud)
我想将其更新为
id | name | ordinal
----+------+---------
1 | A | 3
2 | B | 2
3 | C | 1
Run Code Online (Sandbox Code Playgroud)
尽可能少地接触记录(即不要重写整个记录集,不要启动不必要的触发器),更新为ordinal目标值的通用方法是什么?
普通更新只会给我带来约束违规,即使它发生在单个语句中。
删除并重新创建唯一约束的成本很高,而且并发性很差。
这似乎是一个很常见的问题,应该有一个好的方法来做到这一点,但我只是想不出。