标签: postgresql

优化匹配数组前 N 项的查询

我现在正在使用充满国际象棋游戏数据的 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)

postgresql index optimization array postgresql-performance

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

如何在pg_restore期间设置search_path?

pg_dump 和 pg_restore 会将 search_path 设置为空字符串,如果有函数在没有显式指定模式名称的情况下调用公共模式中的函数(即:uuid_generate_v4()vs public.uuid_generate_v4()),则会失败。

我如何强制pg_restore使用指定的 search_path 例如public

postgresql pg-dump pg-restore

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

PostgeSQL:如果不存在则创建角色/用户?

是否有某种方法可以通过 SQL 在 PostgreSQL 中创建用户/角色/组(仅当用户/角色/组尚不存在时)?到目前为止,我找到的唯一解决方案是创建自定义存储过程,因为它支持条件。有没有我忽略的更简单的解决方案?谢谢你!

postgresql ddl

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

如何替换字符串(文本列)中最后一次出现的字符?

假设我在 Postgres 中有一个具有此值的文本字段:

'bar$foo$john$doe$xxx'
Run Code Online (Sandbox Code Playgroud)

我想将最后一次出现的美元 ( $) 字符替换为另一个字符,例如“-”。替换后该字段的内容应为:

'bar$foo$john$doe-xxx'
Run Code Online (Sandbox Code Playgroud)

postgresql regular-expression replace

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

PostgreSQL 忽略索引,运行 seq 扫描

我的表包含列的索引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)

postgresql index datatypes postgresql-performance

5
推荐指数
2
解决办法
1603
查看次数

与 VM 相比,Azure postgresql 确实很慢

我在带有 docker 的虚拟机上使用 postgresql(和 Postgis)已经很多年了,我开始习惯于调整服务器参数和优化请求,而且我从来没有遇到过使用 Azure Postgresql 时遇到的那种问题。

问题如下:写入速度很慢(通常与普通 PG 相比约为 X2),但真空和索引非常慢。有一次,我们需要在 5 亿行上创建 PostGIS 索引,在另一台服务器上大约需要 30 分钟,在 Azure 实例上则需要一天以上的时间

我尝试修改服务器参数,检查请求,最后回到基础检查服务器的性能,但我仍然不明白是否有我遗漏的东西或者Azure Postgres是否有大问题。

这是我所做的比较:

  • 服务器:
    • PG测试:
      • 托管在虚拟机上的基本 docker postgres 11(SSD,足够的内存和内核,但它并不真正相关)
      • 启动命令:docker run --rm -e POSTGRES_PASSWORD=pass -d postgres:11.14-stretch
    • PG蔚蓝:
      • 适用于 postgresql 的 Azure 数据库,单服务器,内存优化的 8 核,1028Gb 存储
      • 默认服务器参数
  • 从本地 PC 进行测试(我不太关心响应时间):
    • 使用pgbench并创建一个因子为 50 的表 (cmd: pgbench -i -s 50)
    • 查看创建表、vacuum和索引的时间

这是我能找到的最简单且可重现的。确切的结果可能略有不同,但其想法是相同的:

测试结果表明,Azure postgres 创建索引的性能降低了 70 倍

读取性能似乎相当不错,所以这实际上是一个写入问题,对我们来说更成问题的是索引创建,我看不出有什么可以解释这一点。

这对我们来说是一个大问题,我怀疑这种差异可以通过参数的一些调整来改变,除非有特定于 Azure 的东西?

我错过了什么大事吗?只有我有这样的表现吗?还是系统本身的限制?(我读到磁盘大小会影响 IOPS,但查看图表,这里似乎没有问题,我们尝试添加磁盘,但它没有太大变化)也许灵活的服务器没有这个问题?

编辑:

当然,我们测试了使用 3 种不同类型的服务(4 种可能的服务)创建新的 Azure postgres 服务,这些服务是我们刚刚创建的,没有修改。我做了和以前一样的测试,每个服务2次,取平均值。我添加了参考(称为上面的 PG …

postgresql performance azure azure-postgres-database

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

Postgres 中的 EXISTS() 与 EXISTS() = TRUE

面临奇怪的行为EXISTS(也适用于NOT EXISTS)生成不同的执行计划

WHERE EXISTS(...)

EXPLAIN ANALYZE
SELECT * FROM books
WHERE EXISTS (SELECT 1 FROM authors WHERE id = books.author_id AND name LIKE 'asd%');

| QUERY PLAN                                                                                                     |
| -------------------------------------------------------------------------------------------------------------- |
| Hash Join  (cost=218.01..454.43 rows=56 width=40) (actual time=0.975..0.975 rows=0 loops=1)                    |
|   Hash Cond: (books.author_id = authors.id)                                                                    |
|   ->  Seq Scan on books  (cost=0.00..206.80 rows=11280 width=40) (actual time=0.010..0.010 rows=1 loops=1)     |
|   ->  Hash  (cost=217.35..217.35 rows=53 width=4) (actual time=0.943..0.943 rows=0 loops=1)                    |
|         Buckets: …
Run Code Online (Sandbox Code Playgroud)

postgresql exists postgresql-performance

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

PostgreSQL 可以使用索引来加速计数(不同)查询吗?

考虑以下示例:

CREATE TABLE test (
  id SERIAL,
  some_integer INT
);

INSERT INTO test (some_integer)
SELECT FLOOR(RANDOM()*100000) from generate_series(1,100000) s(i);

CREATE INDEX some_integer_idx ON test (some_integer);

EXPLAIN ANALYZE SELECT COUNT(DISTINCT some_integer) from test;
Run Code Online (Sandbox Code Playgroud)

它返回以下查询计划:

CREATE TABLE test (
  id SERIAL,
  some_integer INT
);

INSERT INTO test (some_integer)
SELECT FLOOR(RANDOM()*100000) from generate_series(1,100000) s(i);

CREATE INDEX some_integer_idx ON test (some_integer);

EXPLAIN ANALYZE SELECT COUNT(DISTINCT some_integer) from test;
Run Code Online (Sandbox Code Playgroud)

我很惊讶它仍然在测试中进行顺序扫描。简单地计算索引中的行数不是更快吗?

postgresql index count distinct

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

这是 DELETE ... WHERE EXISTS 查询计划 O(n*2) 还是 O(n^2) ?

我正在尝试执行一项常见任务,从表中删除重复项,目的是添加唯一约束。

CREATE TABLE IF NOT EXISTS item_identifier (
    pk       BIGSERIAL PRIMARY KEY,
    prefix   INTEGER NOT NULL,
    suffix   VARCHAR(1024) NOT NULL
);
CREATE INDEX temp_prefix_suffix_idx ON item_identifier (prefix, suffix);
Run Code Online (Sandbox Code Playgroud)

我想使用常见查询删除重复项,该查询可以在本网站的许多答案中找到。我认为重复率大约为 1%,因此没有太多需要删除的内容。

提供索引纯粹是为了帮助重复数据删除,稍后将被删除。不过,如您所见,PostgreSQL 甚至没有使用它!

有 2,759,559,168 行。索引temp_prefix_suffix_idx本身约为 100 GB。花CREATE INDEX了 12 个小时所以我不指望DELETE会很快。但根据 10% 的样本集,我推断需要 20 小时,而实际上已经花了 40 小时。对于我的示例方法来说,它可能仍在误差范围内,但我担心由于它不使用索引,这将花费指数时间。

EXPLAINSeq Scan on item_identifier aSeq Scan on item_identifier b

EXPLAIN DELETE FROM item_identifier a
  WHERE EXISTS
    (SELECT FROM item_identifier b
       WHERE a.prefix …
Run Code Online (Sandbox Code Playgroud)

postgresql exists query-performance postgresql-performance

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

序列化异常是否只能通过 SUM/COUNT 实现?

我读过《深入了解 MySQL 和 PostgreSQL 中的隔离级别》和《读取现象》,尤其是“Postgres 中的序列化异常”部分。我想我已经理解了那里描述的问题,但是我很难判断它何时会在我的应用程序中发生。

是否只有使用 SUM/COUNT 这样的聚合函数才能在 Postgres 中获得序列化异常?如果不是,我还需要注意什么?

postgresql concurrency isolation-level

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