これは私のテーブルスキーマです
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万件のレコードがあれば、すべて問題ないので、何が起こっているのかわかりません。
デフォルトのオプションでPostresqlServer9.1.5を使用しています。
EXPLAINANALYZEの出力を更新します
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が提案したように新しいインデックスを作成する必要があります。