这是我的表架构
Column | Type | Modifiers
-------------+------------------------+------------------------------------------------------
id | integer | not null default nextval('message_id_seq'::regclass)
date_created | bigint |
content | text |
user_name | character varying(128) |
user_id | character varying(128) |
user_type | character varying(8) |
user_ip | character varying(128) |
user_avatar | character varying(128) |
chatbox_id | integer | not null
Indexes:
"message_pkey" PRIMARY KEY, btree (id)
"idx_message_chatbox_id" btree (chatbox_id)
"indx_date_created" btree (date_created)
Foreign-key constraints:
"message_chatbox_id_fkey" FOREIGN KEY (chatbox_id) REFERENCES chatboxes(id) ON UPDATE CASCADE ON DELETE CASCADE
这是查询
SELECT *
FROM message
WHERE chatbox_id=$1
ORDER BY date_created
OFFSET 0
LIMIT 20;
($ 1将被实际ID替换)
它运行得很好,但是当它达到370万条记录时,所有SELECT查询开始消耗大量的CPU和RAM,然后整个系统崩溃。我必须暂时备份所有当前消息并截断该表。我不知道发生了什么事,因为当我有大约2百万条记录时一切正常
我正在使用Postresql Server 9.1.5和默认选项。
更新EXPLAIN ANALYZE的输出
Limit (cost=0.00..6.50 rows=20 width=99) (actual time=0.107..0.295 rows=20 loops=1)
-> Index Scan Backward using indx_date_created on message (cost=0.00..3458.77 rows=10646 width=99) (actual time=0.105..0.287 rows=20 loops=1)
Filter: (chatbox_id = 25065)
Total runtime: 0.376 ms
(4 rows)
更新服务器规范
Intel Xeon 5620 8x2.40GHz+HT
12GB DDR3 1333 ECC
SSD Intel X25-E Extreme 64GB
最终解决方案
最后我可以查看超过300万条消息,我必须像wildplasser建议的那样优化postgresql配置,并且还建立一个新的索引,如A.H.建议
答案 0 :(得分:8)
您可以尝试为PostgreSQL提供更好的查询索引。我建议这样的事情:
create index invent_suitable_name on message(chatbox_id, date_created);
或
create index invent_suitable_name on message(chatbox_id, date_created desc);
答案 1 :(得分:3)
尝试为chatbox_id, date_created
添加索引。对于此特定查询,它将为您提供最佳性能。
对于这种情况,当postgres“开始消耗大量CPU和RAM”时,尝试获取更多细节。它可能是一个错误(默认配置postgres通常不会消耗太多RAM)。
UPD我对性能不佳的猜测:
在某个时间点,表格变得很大以进行全面扫描以收集准确的统计数据。在另一个ANALYZE
Postgresql获得该表的错误统计信息之后。结果 - 得到了糟糕的计划,包括:
chatbox_id
; 由于在步骤1返回的默认配置和大量记录,postgres被迫在磁盘上的文件中进行排序。结果 - 性能不佳。
UPD2 EXPALIN ANALYZE
显示0.376 ms
时间和良好的计划。你能否详细介绍一个性能不佳的案例?