这是我的表架构
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,然后整个系统出现故障。我必须临时备份所有当前消息并截断该表。我不确定发生了什么,因为当我有大约 200 万条记录时一切正常
我正在使用带有默认选项的 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 配置,并按照 AH 的建议创建一个新索引