考虑这两个查询:
SELECT
t1.id, *
FROM
t1
INNER JOIN
t2 ON t1.id = t2.id
where t1.id > -9223372036513411363;
Run Code Online (Sandbox Code Playgroud)
和:
SELECT
t1.id, *
FROM
t1
INNER JOIN
t2 ON t1.id = t2.id
where t1.id > -9223372036513411363 and t2.id > -9223372036513411363;
Run Code Online (Sandbox Code Playgroud)
注意:不是-9223372036513411363表中的最小值,并且条件将结果(从总行数 3.5 亿行)减少到 1700 万行。
就我个人而言,我希望 PostgreSQL 能够为这两个查询提供相同的计划,因为t1.id = t2.id自动意味着第二个条件。但不幸的是,PostgreSQL 正在创建两个不同的计划,第二个计划要好得多:
我非常喜欢第一个查询,因为我想从连接创建一个视图,并将 where 条件放在视图上的查询上,我在其中看到单个 id 列(我使用连接,USING因此单个 id 列在视图中可见) 。另外,我将连接两个以上的表,并且我不希望为每个连接添加这样的条件。
这种行为有什么原因吗?或者这是一个错误?有什么解决方法吗?
ON …postgresql performance join execution-plan postgresql-9.3 postgresql-performance
我正在评估 PostgreSQL 作为 Oracle 的替代品。我有一个包含 533 个表的数据库,其中最多包含 250,000 个条目。
\n\n为了进行性能比较,我在 Oracle 和 PostgreSQL 上构建了数据库。
\n\n然而,PostgreSQL 速度慢得多,并且它在 RAM 中存储的内容不多,而是具有大量的磁盘 I/O。
\n\n我的性能测试:
\n\n我的系统配置:
\n\n以下是我测量的性能(5 次运行的平均值):
\n\n\n\nNoTriggers 版本以ALTER TABLE x DISABLE ALL TRIGGERS.
从图表中可以看出,PostgreSQL 并没有真正使用可用的 ram。\n查看资源监视器,它确实使用了高磁盘 io:
\n\n …postgresql performance performance-testing postgresql-performance
这是一个关于 Postgres (v10) 的内部工作原理和性能的问题。
给定一个表 ,在和列github_repos上具有多列唯一索引,下面的两个批量更新插入操作之间是否存在任何性能差异(或其他需要注意的问题)?不同之处在于,在第一个查询中,和列包含在 UPDATE 中,而在第二个查询中则不包含。由于 UPDATE 在冲突时运行,因此和的更新值将与旧值相同,但这些列包含在 UPDATE 中,因为我正在使用的底层库就是这样设计的。我想知道按原样使用是否安全,或者我是否应该在更新中明确排除这些列。org_idgithub_idorg_idgithub_idorg_idgithub_id
查询#1:
INSERT INTO "github_repos" ("org_id","github_id","name")
VALUES (1,1,'foo')
ON CONFLICT (org_id, github_id)
DO UPDATE SET "org_id"=EXCLUDED."org_id","github_id"=EXCLUDED."github_id","name"=EXCLUDED."name"
RETURNING "id"
Run Code Online (Sandbox Code Playgroud)
查询#2:
INSERT INTO "github_repos" ("org_id","github_id","name")
VALUES (1,1,'foo')
ON CONFLICT (org_id, github_id)
DO UPDATE SET "name"=EXCLUDED."name"
RETURNING "id"
Run Code Online (Sandbox Code Playgroud)
github_repos桌子:
Column | Type | Collation | Nullable
-------------------+-------------------+-----------+----------+
id | bigint | | not null |
org_id | bigint | | not null | …Run Code Online (Sandbox Code Playgroud) postmaster与尝试插入低容量行的客户端连接相关的子进程的 CPU 使用率较高(导致插入的行比使用相同行慢 25 倍)。COPY ... FROM STDIN
尝试识别系统/数据库配置以缓解上述较差的插入性能。我正在使用多线程 R 脚本来处理数据并将结果插入到 PostgreSQL 数据库中。我对 R 脚本进行了分析,以隔离调用的性能瓶颈DBI::dbBind(),同时用于top监视postmaster与子 R 线程打开的连接关联的子进程(请参阅下面的代码)。在 INSERT 期间,R 子进程大部分时间处于空闲状态(大概是在等待调用返回DBI::dbBind()),而postmaster子进程在其运行大约 2-3 分钟的时间内消耗了 95-100% 的 CPU。
uname -a:Linux localhost 4.16.6-202.fc27.x86-64 #1 SMP Wed May 2 00:09:32 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux/proc/cpuinfo: 16 个处理器 ( Intel(R) Xeon(R) CPU D-1541 @ 2.10GHz)ulimit …
postgresql performance configuration r postgresql-10 postgresql-performance
我有一个数据库,其中有一列名为timestamptype timestamp without timezone,该列上有一个 btree 索引。
我有一个查询如下
SELECT
*
FROM
employee
WHERE
timestamp >= timestamp '2020-01-27 13:24:09'
Run Code Online (Sandbox Code Playgroud)
timestamp但是,解释分析显示未使用该列上的索引:
Seq Scan on employee (cost=0.00..5498.73 rows=34377 width=381) (actual time=0.016..37.944 rows=34251 loops=1)
Filter: ("timestamp" >= '2020-01-27 13:24:09'::timestamp without time zone)
Rows Removed by Filter: 21167
Planning Time: 0.255 ms
Execution Time: 40.277 ms
Run Code Online (Sandbox Code Playgroud)
如果我使用包含时间戳的过滤条件更改查询,而不是1 month(1 year如上所述),则使用列上的索引。
Bitmap Heap Scan on employee (cost=59.51..4510.25 rows=2996 width=381) (actual time=2.164..5.204 rows=2958 loops=1)
Recheck Cond: ("timestamp" >= '2020-12-27 13:24:09'::timestamp without …Run Code Online (Sandbox Code Playgroud) 我这里有一个非常奇怪的问题。我们的搜索查询接收多个参数并通过不同表中的多个联接进行搜索。查询在我们运行的前几次运行良好,然后有时会严重减慢,例如:从 200 毫秒到 15000/20000 毫秒。在同一个查询上。
最初我认为这是后端 ORM 问题,但在彻底检查并打开慢速查询日志、打开 auto_explain 功能后,我意识到查询计划在几次调用后发生了变化。我们在后端放置一个循环,在同一线程上多次执行查询(用于测试),我发现几乎总是在执行 8 次后数据库开始记录慢速查询。最后结果是查询计划发生了变化。最重要的变化是(我认为)TimeSlots 表上的变化,从 seq 扫描到位图索引扫描,它估计的行数比表中的行数少得多。估计:566 实际:100 000 左右。
我之前尝试过的事情:
这是选择语句:
SELECT DISTINCT u."UserId" AS UserId,
cast(cuj.company_id as bigint) AS CompanyId,
cast(ts.SlotsCount as bigint) as SlotsCount,
case when cuj.vip is null then false else cuj.vip end vip,
u.is_vip as userVip,
case
when ts2.EarliestDate isnull then '7777-12-01 21:00:00.000000'
else ts2.EarliestDate …Run Code Online (Sandbox Code Playgroud) 想象一个视图,其中包含来自两个不同表的COALESCE两varchar列。
底层证券varchars在两个表中都有索引。
在 Postgres 11.6 中,根据结果过滤此视图COALESCE不使用索引,而是进行表扫描。
但是,如果我将列更改为text,在同一列上过滤完全相同的视图,则索引将按您的预期使用。
假设我有一个一些标识符随时间变化的测量值表。还有一个几乎相同的表,其中包含估计值:
CREATE TABLE measured (
id int,
ts timestamp,
identifier character varying,
measured_value int
);
CREATE INDEX ON measured(identifier);
CREATE TABLE estimated (
id int,
ts timestamp,
identifier character varying,
estimated_value int
);
CREATE INDEX ON estimated(identifier);
Run Code Online (Sandbox Code Playgroud)
每个表有 100 万行数据:
INSERT INTO measured
SELECT
generate_series(1, 1000000),
to_timestamp((random() * 100000)::int),
left(md5(random()::text), 2),
random() * 10;
INSERT INTO estimated
SELECT
generate_series(1, 1000000),
to_timestamp((random() * …Run Code Online (Sandbox Code Playgroud) postgresql varchar execution-plan index-tuning postgresql-performance
我现在正在使用充满国际象棋游戏数据的 Postgres 数据库,其中每个游戏都是“记录”表中的一行。玩家的动作和这些动作的(可选)计算机评估都有自己的列并存储为数组。
我编写了一个查询来检索指定的开局动作序列的所有评估。(你可能认为计算机的评估会是一致的 - 但事实并非如此。)开局序列的长度是任意的 - 可以是一步,也可以是三十步。
下面是一个示例查询,它查找以相同的十步开局序列开始的所有游戏,然后对于每个带有评估的游戏,返回计算机对游戏中该点的评估 -
SELECT evaluation[10]
FROM records
WHERE moves[1:10]::text[] = ARRAY['b4', 'e5', 'Bb2', 'd6', 'Nf3', 'Nf6', 'g3', 'Bg4', 'Bg2', 'h5']::text[]
AND evaluation IS NOT NULL;
Run Code Online (Sandbox Code Playgroud)
我不确定它是否相关,但移动数据始终是 2-6 个字符的字母数字字符串,并且计算机评估大部分是小数(正数和负数),但确实包括偶尔的特殊字符(强制将死者有一个 octothorpe前缀)。
这是表描述的相关片段 -
Column | Type |
-----------------+--------------------------------+-
id | bigint |
moves | character varying(255)[] |
evaluation | character varying(255)[] |
"records_pkey" PRIMARY KEY, btree (id)
Access method: heap
Run Code Online (Sandbox Code Playgroud)
这是来自 EXPLAIN ANALYZE 的查询计划:
Gather (cost=1000.00..736354.70 rows=905 width=516) (actual time=28251.267..28253.139 rows=0 loops=1)
Workers Planned: 2 …Run Code Online (Sandbox Code Playgroud) 我的表包含列的索引total_balance:
\d balances_snapshots
Table "public.balances_snapshots"
Column | Type | Collation | Nullable | Default
---------------+-----------------------------+-----------+----------+------------------------------------------------
user_id | integer | | |
asset_id | text | | |
timestamp | timestamp without time zone | | | now()
total_balance | numeric | | not null |
id | integer | | not null | nextval('balances_snapshots_id_seq'::regclass)
Indexes:
"balances_snapshots_pkey" PRIMARY KEY, btree (id)
"balances_snapshots_asset_id_idx" btree (asset_id)
"balances_snapshots_timestamp_idx" btree ("timestamp")
"balances_snapshots_user_id_idx" btree (user_id)
"balances_total_balance_idx" btree (total_balance)
Foreign-key constraints:
"balances_snapshots_asset_id_fkey" FOREIGN KEY (asset_id) …Run Code Online (Sandbox Code Playgroud) 在PG中你可以创建一个像这样的表
CREATE TABLE foo (
id uuid PRIMARY KEY DEFAULT gen_random_uuid (),
name text NOT NULL,
things text[] NOT NULL DEFAULT ARRAY[] ::text[]
)
Run Code Online (Sandbox Code Playgroud)
以及相关索引
CREATE INDEX foo_text ON foo USING btree (name, things);
Run Code Online (Sandbox Code Playgroud)
但很难找到有关其作用的信息。我继承了一个像这样的表(数亿行,尽管这个数组几乎总是有 0 或 1 个条目),并且索引确实在 pg_stat_all_indexes 中偶尔命中,所以至少在某些情况下可以发生了,但我也注意到,相对于其他索引,该索引占用了大量空间,并且清理速度要慢得多。 PG 中数组字段的索引有意义吗?btree
如果目标是能够找到things包含所提供的一个或多个值的行,是否有更好的方案?(假设我们此时无法将其正确规范化为它自己的表。)
我们期望查询会命中该索引,如下所示
SELECT id FROM foo
WHERE name = $1
AND $2::text = ANY(things)
Run Code Online (Sandbox Code Playgroud)
SELECT id FROM FOO
WHERE name = $1
AND things @> $2::text[]
Run Code Online (Sandbox Code Playgroud) postgresql ×10
index ×4
performance ×4
array ×2
index-tuning ×2
datatypes ×1
join ×1
optimization ×1
r ×1
varchar ×1