我现在正在使用充满国际象棋游戏数据的 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) pg_dump 和 pg_restore 会将 search_path 设置为空字符串,如果有函数在没有显式指定模式名称的情况下调用公共模式中的函数(即:uuid_generate_v4()vs public.uuid_generate_v4()),则会失败。
我如何强制pg_restore使用指定的 search_path 例如public?
是否有某种方法可以通过 SQL 在 PostgreSQL 中创建用户/角色/组(仅当用户/角色/组尚不存在时)?到目前为止,我找到的唯一解决方案是创建自定义存储过程,因为它支持条件。有没有我忽略的更简单的解决方案?谢谢你!
假设我在 Postgres 中有一个具有此值的文本字段:
'bar$foo$john$doe$xxx'
Run Code Online (Sandbox Code Playgroud)
我想将最后一次出现的美元 ( $) 字符替换为另一个字符,例如“-”。替换后该字段的内容应为:
'bar$foo$john$doe-xxx'
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) 我在带有 docker 的虚拟机上使用 postgresql(和 Postgis)已经很多年了,我开始习惯于调整服务器参数和优化请求,而且我从来没有遇到过使用 Azure Postgresql 时遇到的那种问题。
问题如下:写入速度很慢(通常与普通 PG 相比约为 X2),但真空和索引非常慢。有一次,我们需要在 5 亿行上创建 PostGIS 索引,在另一台服务器上大约需要 30 分钟,在 Azure 实例上则需要一天以上的时间。
我尝试修改服务器参数,检查请求,最后回到基础检查服务器的性能,但我仍然不明白是否有我遗漏的东西或者Azure Postgres是否有大问题。
这是我所做的比较:
docker run --rm -e POSTGRES_PASSWORD=pass -d postgres:11.14-stretchpgbench -i -s 50)这是我能找到的最简单且可重现的。确切的结果可能略有不同,但其想法是相同的:
读取性能似乎相当不错,所以这实际上是一个写入问题,对我们来说更成问题的是索引创建,我看不出有什么可以解释这一点。
这对我们来说是一个大问题,我怀疑这种差异可以通过参数的一些调整来改变,除非有特定于 Azure 的东西?
我错过了什么大事吗?只有我有这样的表现吗?还是系统本身的限制?(我读到磁盘大小会影响 IOPS,但查看图表,这里似乎没有问题,我们尝试添加磁盘,但它没有太大变化)也许灵活的服务器没有这个问题?
编辑:
当然,我们测试了使用 3 种不同类型的服务(4 种可能的服务)创建新的 Azure postgres 服务,这些服务是我们刚刚创建的,没有修改。我做了和以前一样的测试,每个服务2次,取平均值。我添加了参考(称为上面的 PG …
面临奇怪的行为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) 考虑以下示例:
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)
我很惊讶它仍然在测试中进行顺序扫描。简单地计算索引中的行数不是更快吗?
我正在尝试执行一项常见任务,从表中删除重复项,目的是添加唯一约束。
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 小时。对于我的示例方法来说,它可能仍在误差范围内,但我担心由于它不使用索引,这将花费指数时间。
这EXPLAIN有Seq Scan on item_identifier a和Seq 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) 我读过《深入了解 MySQL 和 PostgreSQL 中的隔离级别》和《读取现象》,尤其是“Postgres 中的序列化异常”部分。我想我已经理解了那里描述的问题,但是我很难判断它何时会在我的应用程序中发生。
是否只有使用 SUM/COUNT 这样的聚合函数才能在 Postgres 中获得序列化异常?如果不是,我还需要注意什么?
postgresql ×10
index ×3
exists ×2
array ×1
azure ×1
concurrency ×1
count ×1
datatypes ×1
ddl ×1
distinct ×1
optimization ×1
performance ×1
pg-dump ×1
pg-restore ×1
replace ×1