我有数据拉取功能,可以在 5 秒内根据modified_timestamp列从 Postgres 表中抓取所有数据。它的工作方式如下:
SELECT * FROM my_table WHERE modified_timestamp > _some_persisted_timestamp其中modified_timestamp使用触发器更新(在任何行更新modified_timestamp变为 之后CURRENT_TIMESTAMP)。它工作正常,直到我注意到CURRENT_TIMESTAMPPostgres 实际上是事务开始时间戳并且一些更新丢失了。他们为什么会迷路?这很简单 - 在我执行查询时,SELECT * FROM my_table WHERE modified_timestamp > _some_persisted_timestamp一些更改已经发生,但modified_timestamp在更新_some_persisted_timestamp之前,因为事务仍在进行中。
当更新对其他事务可见(换句话说,事务提交时间戳)而不是 CURRENT_TIMESTAMP 或 clock_timestamp()时,可以通过在步骤 2 中 分配时间戳来轻松解决此问题。
我阅读了文档,但没有发现与事务提交时间戳相关的任何内容。你能不能给点建议?
顺便说一句,我知道逻辑解码,我知道这种机制在理论上更适合我的需求,但有一些实际问题不允许我使用它。
我试图了解从视图中选择数据的性能影响,其中视图中的一列是原始表中其他数据的函数。
无论计算列是否在所选列的列表中,是否都会执行计算?
如果我有一张桌子并且视图像这样声明
CREATE TABLE price_data (
ticker text, -- Ticker of the stock
ddate date, -- Date for this price
price float8, -- Closing price on this date
factor float8 -- Factor to convert this price to USD
);
CREATE VIEW prices AS
SELECT ticker,
ddate,
price,
factor,
price * factor as price_usd
FROM price_data
Run Code Online (Sandbox Code Playgroud)
会是乘法类似下面的查询来执行?
select ticker, ddate, price, factor from prices
Run Code Online (Sandbox Code Playgroud)
是否有参考以一种方式或另一种方式保证这一点?我正在阅读有关 Postgres 规则系统的文档,但我认为答案确实在于优化器,因为规则系统文档中没有任何内容表明它不会被选中。
我怀疑在上述情况下没有执行计算。我将视图更改为使用除法而不是乘法,并将0for插入factor到price_data. 上面的查询没有失败,但如果修改查询以选择计算列,则修改后的查询失败。
有什么方法可以理解在执行 a 时 …
我有一个大型 Postgres 表,其中包含 2+ 十亿个条目(1.5TB),并且大部分是非空的 char var 列。为了加快插入速度,我在批量上传之前删除了索引。但是,现在创建 b 树索引需要很长时间。对于我缩短的运行之一,它花了超过 12 个小时创建索引。
我正在尝试制作的示例表和索引:
Column | Type | Modifiers
-----------------------+-----------------------------+-----------
name | character varying | not null
id | character varying |
lifecycle_id | character varying |
dt | character varying |
address | character varying |
...
Indexes:
"name_idx" PRIMARY KEY, btree (name)
"id_idx" btree (rec_id)
"lifecycle_id_idx" btree (lifecycle_id)
Run Code Online (Sandbox Code Playgroud)
实际表有 18 列。我已将 maintenance_work_mem 设置为 15GB。这是在 RDS 上的 Postgres 9.6.11 上运行的。实例类是 db.m4.4xlarge。
由于有三个索引,在插入之前很难对数据进行排序。只插入数据而不删除索引会更快吗?还有其他加快索引创建的建议吗?
我看到了这个问题Bit vs. Boolean columns。
对于 Postgres,我问自己同样的问题:一位整数列是否占用了布尔值列的相同磁盘空间?在大表(约 50 列 x 约 5000 万行)中,哪一个表现最好?我怎样才能找到这个?
postgresql performance database-design optimization disk-space postgresql-performance
我在 Postgres 表中有一个jsonb列。它包含以下数据:datamy_table
[
{"id":"1","status":"test status1","updatedAt":"1571145003"},
{"id":"2","status":"test status2","updatedAt":"1571145323"}
]
Run Code Online (Sandbox Code Playgroud)
我想updatedAt使用一个查询更新该数组中所有对象的键。我试过:
update my_table set data = data || '{"updatedAt": "1571150000"}';
Run Code Online (Sandbox Code Playgroud)
上面的查询在数组中添加了一个新对象,如下所示:
[
{"id":"1","status":"test status1","updatedAt":"1571145003"},
{"id":"2","status":"test status2","updatedAt":"1571145323"},
{"updatedAt":"1571150000"}
]
Run Code Online (Sandbox Code Playgroud)
我想要的输出如下:
[
{"id":"1","status":"test status1","updatedAt":"1571150000"},
{"id":"2","status":"test status2","updatedAt":"1571150000"}
]
Run Code Online (Sandbox Code Playgroud)
我也尝试过jsonb_set(),但这需要第二个参数是数组索引。我无法确定数组中 JSON 对象的数量。
如果可以通过自定义函数解决这个问题,也很好。
我有下表:
id time_start area
1 2019-09-01T10:12:32Z london
2 2019-08-29T10:13:32Z chicago
3 2019-07-31T10:14:32Z paris
4 2019-09-28T10:17:32Z madrid
5 2019-07-04T10:18:32Z spain
Run Code Online (Sandbox Code Playgroud)
我想添加一个名为 Correct_date 的新列,它只是 time_start 列:
新列应添加到末尾,如下所示:
date_start
2019-09-01
2019-08-29
2019-07-31
2019-09-28
2019-07-04
Run Code Online (Sandbox Code Playgroud)
但是,我事先根据 where 语句过滤数据,并且有点困惑如何在满足 where 条件后更改表 - 或者以哪种顺序执行该过程?我知道我必须使用 timestamp::date 来获取日期。
我当前的查询是
select *
from
my_table
where area in ('london','chicago','paris')
Run Code Online (Sandbox Code Playgroud)
如何在上面的代码中添加一个 alter table 语句,以便它根据 time_start 列的日期添加一个新列 - 我会在开头执行 alter 语句吗?
使用 postgresql 无法在线找到明确的答案!
目前我正在试图创建一个表,一个文本列将比较案例在默认情况下是敏感的。这是因为我们有一个第三方程序可以对我们的数据库执行搜索。该SELECT程序使用的语句不能更改。
抽象的问题是我们不知何故需要这个搜索不区分大小写,但它目前是区分大小写的。
我读到 Postgres 12 确实支持允许这种行为的非确定性排序规则。
我在德国 Windows 机器上安装了 Postgres 服务器(版本 PostgreSQL 12.1,由 Visual C++ build 1914 编译,64 位)。
因此,出于测试目的,我创建了一个新数据库进行测试:
CREATE DATABASE collation_test
WITH
OWNER = postgres
ENCODING = 'UTF8'
CONNECTION LIMIT = -1;
Run Code Online (Sandbox Code Playgroud)
在这个数据库中,我创建了以下排序规则,我在一篇关于这些排序规则的文章中找到了
CREATE COLLATION collat_ci (
provider = 'icu',
locale = 'und-u-ks-level2',
deterministic = false
);
Run Code Online (Sandbox Code Playgroud)
在此之后,我需要一个表来测试这个排序规则
CREATE TABLE public.person
(
"Id" bigint NOT NULL,
"Name" text COLLATE public.collat_ci,
PRIMARY KEY ("Id")
);
ALTER TABLE public.person
OWNER to postgres;
INSERT …Run Code Online (Sandbox Code Playgroud) 从创建的角度来看,假设在 Postgres 中通过自动递增的 PK 排序将按时间顺序对记录进行排序是否安全?我有一个多对多的关系,除了关系本身和某种形式的创建顺序之外,我不需要跟踪其他任何东西。我正在尝试决定是否需要为此合并时间戳列,或者是否可以出于相同目的重新利用现有的自动递增 PK 列。
我有桌子currency_pair(c1, c2);值是(usd,bnb), (cake,bnb), (cake,eth)。
我需要找到一个让我比较的最短路径usd来eth。
此处的结果将是相同的值。然后我可以使用第一对建立一个 usd-bnb 关系,然后我可以用它来计算 usd-cake 关系,然后我可以用它来计算 usd-eth。
由于顺序是不确定的,我做的第一步是创建一个物化视图,currency_pair_map(c1, c2),它是 的并集select c1, c2 union select c2, c1。这似乎简化了逻辑。
如果我正确考虑这一点,我需要做的是使用WITH RECURSIVE?我还应该有某种“depth_limit”参数,以确保在无法建立一对时查询失败。
大声思考这个问题,我们应该始终从以下几点开始:
SELECT *
FROM currency_pair
WHERE
c1 = 'usd' AND
c2 = 'eth'
Run Code Online (Sandbox Code Playgroud)
如果有结果,我们应该到此为止。
如果没有,那么我们需要找到所有usd-*对并继续搜索,直到找到以 结尾的对eth。
使用这个逻辑,到目前为止我有:
WITH RECURSIVE pair_route AS (
SELECT
1 depth,
cp1.id,
cp1.c1,
cp1.c2
FROM currency_pair cp1
WHERE
cp1.c1 = 'usd'
UNION
SELECT
pr1.depth + 1, …Run Code Online (Sandbox Code Playgroud) 想象一下,我在 Postgres 13 中有一个像这样的表:
CREATE TABLE public.people (
id integer PRIMARY KEY,
full_name character varying(255),
bio text
);
Run Code Online (Sandbox Code Playgroud)
然后,我插入一行,其中包含足够的字符,以便将 Bio 写入 TOAST 表(4000 个随机字节,应压缩到 > 2Kb):
# insert into people values (1, 'joe toast', (SELECT array_to_string(ARRAY(SELECT chr((65 + round(random() * 25)) :: integer) FROM generate_series(1,4000)), '')));
INSERT 0 1
Run Code Online (Sandbox Code Playgroud)
然后插入一行,其中包含足够的字符用于 Bio Fit 内联(3000 个重复字节,应压缩至 < 2Kb):
# insert into people values (2, 'joe compressed', (SELECT array_to_string(ARRAY(SELECT chr(65) FROM generate_series(1,3000)), '')));
INSERT 0 1
Run Code Online (Sandbox Code Playgroud)
最后在简介中插入一行仅包含几个字符的行,以便它将存储内联(10 个重复字节):
# insert into people values …Run Code Online (Sandbox Code Playgroud) postgresql ×10
collation ×1
disk-space ×1
json ×1
json-path ×1
optimization ×1
performance ×1
primary-key ×1
recursive ×1
sequence ×1
timestamp ×1
update ×1
view ×1