我们的系统写入了大量数据(一种大数据系统)。写入性能足以满足我们的需求,但读取性能真的太慢了。
我们所有表的主键(约束)结构都相似:
timestamp(Timestamp) ; index(smallint) ; key(integer).
Run Code Online (Sandbox Code Playgroud)
一个表可以有数百万行,甚至数十亿行,而一个读请求通常是针对特定时间段(时间戳/索引)和标记的。查询返回大约 20 万行是很常见的。目前,我们每秒可以读取大约 15k 行,但我们需要快 10 倍。这是可能的,如果是,如何?
注意: PostgreSQL 是和我们的软件一起打包的,所以不同客户端的硬件是不一样的。
它是一个用于测试的虚拟机。VM 的主机是具有 24.0 GB RAM 的 Windows Server 2008 R2 x64。
Server 2008 R2 x64
2.00 GB of memory
Intel Xeon W3520 @ 2.67GHz (2 cores)
Run Code Online (Sandbox Code Playgroud)
postgresql.conf 优化shared_buffers = 512MB (default: 32MB)
effective_cache_size = 1024MB (default: 128MB)
checkpoint_segment = 32 (default: 3)
checkpoint_completion_target = 0.9 (default: 0.5)
default_statistics_target = 1000 (default: 100)
work_mem = 100MB (default: 1MB)
maintainance_work_mem = 256MB …Run Code Online (Sandbox Code Playgroud) 我有一个旧模式(免责声明!),它使用基于哈希生成的 id 作为所有表的主键(有很多)。这种 id 的一个例子是:
922475bb-ad93-43ee-9487-d2671b886479
Run Code Online (Sandbox Code Playgroud)
改变这种方法是不可能的,但是索引访问的性能很差。撇开这可能的无数原因不谈,我注意到有一件事似乎不太理想 - 尽管所有许多表中的所有 id 值的长度都正好是 36 个字符,但列类型是varchar(36),而不是 char(36)。
将列类型更改为固定长度是否会char(36)提供任何显着的索引性能优势,除了每个索引页的条目数量增加很小等之外?
即在处理固定长度类型时 postgres 的执行速度是否比处理可变长度类型快得多?
请不要提及微小的存储节省 - 与对列进行更改所需的手术相比,这无关紧要。
我有一个表,需要添加一个没有默认值的新列:
ALTER TABLE integrations.billables
DROP CONSTRAINT IF EXISTS cc_at_least_one_mapping_needed_billables,
ADD CONSTRAINT cc_at_least_one_mapping_needed_billables
CHECK ((("qb_id" IS NOT NULL) :: INTEGER +
("xero_id" IS NOT NULL) :: INTEGER +
("freshbooks_id" IS NOT NULL) :: INTEGER +
("unleashed_id" IS NOT NULL) :: INTEGER +
("csv_data" IS NOT NULL) :: INTEGER +
("myob_id" IS NOT NULL) :: INTEGER) > 0);
Run Code Online (Sandbox Code Playgroud)
ALTER TABLE integrations.billables
DROP COLUMN IF EXISTS myob_id,
ADD COLUMN myob_id varchar(255);
Run Code Online (Sandbox Code Playgroud)
如何为下一个值添加约束,而不是为那些已经存在的值添加约束?(否则我会得到某些行违反了错误检查约束“”)。
这与我之前的问题有关:错误:某些行违反了检查约束
postgresql null database-design postgresql-9.2 check-constraints
我现在正在使用充满国际象棋游戏数据的 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) 我对索引列的查询速度非常慢。鉴于查询
SELECT *
FROM orders
WHERE shop_id = 3828
ORDER BY updated_at desc
LIMIT 1
Run Code Online (Sandbox Code Playgroud)
explain analyze 回来:
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=0.43..594.45 rows=1 width=175) (actual time=202106.830..202106.831 rows=1 loops=1)
-> Index Scan Backward using index_orders_on_updated_at on orders (cost=0.43..267901.54 rows=451 width=175) (actual time=202106.827..202106.827 rows=1 loops=1)
Filter: (shop_id = 3828)
Rows Removed by Filter: 1604818
Planning time: 98.579 ms
Execution time: 202127.514 ms
(6 rows)
Run Code Online (Sandbox Code Playgroud)
表说明为:
Table "public.orders"
Column | Type | Modifiers
--------------------+-----------------------------+---------------------------------------------------------------
id | integer | not null default nextval('orders_id_seq'::regclass) …Run Code Online (Sandbox Code Playgroud) postgresql ×5
performance ×3
index ×2
amazon-rds ×1
array ×1
index-tuning ×1
null ×1
optimization ×1
order-by ×1
varchar ×1