我有一张约240万条记录的表格。 通过索引字段进行8000次后续选择需要~2.0秒才能执行(仅返回5个值)。所以它大约有4000个查询/秒,我发现它很慢。
表格如下
CREATE TABLE hashes
(
id bigserial NOT NULL,
hash bytea NOT NULL,
ref_id integer,
ref_loc bigint,
ref_len integer
);
hash 字段有一个索引。
CREATE UNIQUE INDEX ix_hashes_hash ON hashes USING BTREE (hash);
hash 列填充了16字节的唯一值。
我从pgAdmin:
一批运行8000行SELECT id,hash FROM hashes WHERE hash=decode('04c04695137724288078eb81ac648841', 'hex');
...
SELECT id,hash FROM hashes WHERE hash=decode('632a1c158d1a470e4506b08a2e16d239', 'hex');
并且需要2秒才能执行。
我的研究表明:
EXPLAIN(ANALYZE,VERBOSE)返回的单个SELECT查询的执行计划:
"Index Scan using pk_blocks_hash on public."Blocks" (cost=0.43..8.45 rows=1 width=25) (actual time=0.025..0.025 rows=0 loops=1)"
" Output: id, hash"
" Index Cond: ("Blocks".hash = '\373\355\341\264\200\234\210\3722\352\204L\252\355\021v'::bytea)"
"Planning time: 0.175 ms"
"Execution time: 0.076 ms"
我可以在执行postgres.exe进程时看到一个perf峰值: CPU跃升至25% 内存使用量跃升至185Mb(从6mb)
按照PgTune的建议修改postgresql.conf(当然重启Postgres):
max_connections = 20
shared_buffers = 512MB
effective_cache_size = 6GB
work_mem = 64MB
maintenance_work_mem = 1GB
min_wal_size = 4GB
max_wal_size = 8GB
checkpoint_completion_target = 0.9
wal_buffers = 16MB
default_statistics_target = 500
无济于事。
将所有请求的哈希值放入单个查询中会有所帮助:我只用330毫秒来获得:
SELECT id,hash
FROM hashes
WHERE hash IN (decode('04c04695137724288078eb81ac648841', 'hex'),
...
decode('632a1c158d1a470e4506b08a2e16d239', 'hex'));
但并不总是可以将多个查询组合在一起,而且不能解释查询性能慢的问题。
好吧,我希望每秒不少于50,000个这样的查询。
我对此服务器要求太多吗? 或者我做错了什么?
环境: