2017-01-13 4 views
0

postgresql 9.5.2をRDSインスタンスで実行します。私たちが気付いたことは、特定のテーブルが時には非常に急速に成長することでした。postgresqlの高速増殖テーブル

問題のテーブルは33k行と〜600列しかありません。すべての列は数値です(小数点(25,6))。真空がいっぱいになった後、次のクエリで報告された「total_bytes」は

select c.relname, pg_total_relation_size(c.oid) AS total_bytes 
from pg_class c; 

約150MBです。しかし、これは71GBまで拡大しました。最近のエピソードでは、total_bytesは30分で10GB増加しました。

上記のエピソードでは、テーブルのすべてのレコードを更新する毎分〜4回実行されるバッチ更新クエリがありました。しかし、他の時間には、同様の更新アクティビティにもかかわらずテーブルサイズは一定のままでした。

これはおそらく、「死んだレコード」がアップデートから残されていることが原因であると私は理解します。実際にこのテーブルが大きくなり過ぎると、真空が完全に稼働すると通常のサイズ(150M)に縮小されます。私の質問は

  • は、他の人は、PostgreSQLのテーブルサイズで同様の急速な成長を経験しているしている、これは正常ですか?

  • 私たちのバッチ更新クエリがテーブルサイズの急激な増加を引き起こしている場合、なぜ毎回それが起こらないのですか?実際、私は

    更新my_tableに集合X = X * 2

のようなものを実行して、手動で再現することを試みたができなかった - テーブルのサイズは、クエリの前と後に同じままでした。

+1

600個の列がデータベースデザインのように聞こえます。レコードが急速に追加された場合、特にそれらの列の多くがかなりの量の領域を使用する場合は、サイズが非常に速く膨張することは驚くことではありません。 –

答えて

1

問題は、1つのテーブルに600個の列があることです。決して良い考えではありません。これは多くの問題を引き起こすだろう、テーブルのサイズはそれらの一つです。

PostgreSQL docs ...

から[数値の】実際のストレージ要件は、4桁のグループごとに2バイトであり、加えて3〜8バイトのオーバーヘッド。

したがってdecimal(25, 6)は、8 +(31/4 * 2)または1列あたり約24バイトのようなものです。 1行につき600列で、行あたり約14,400バイト、または行あたり約14KBです。 33,000行で約450メガバイトです。

毎分4回ずつ行を更新している場合は、毎分約1.8ギグ/分の行が残されます。

  1. スキーマ設計を修正する必要があります。
  2. テーブルのすべての行を1分間に4回タッチする必要はありません。

この表とプロセスの再設計に関する質問があります。

+0

600列のテーブルのもう1つの問題は、基本ストレージが1行につき8kBに上限があることです。実際にこれらの列のそれぞれに25桁の数字を入力しようとすると[適合しません。 。](http://rextester.com/GAKZH12768) –

+0

なぜ、私はこの問題を再現できなかったのですか?すべてのレコードを更新するupdate table_name set x = x * 2を実行していますか? – yan479

+0

@ yan479おそらく、既存のストレージに収まるので、再割り当てする必要はありませんでしたか?それを乱数に設定してみてください。または、トランザクションに参加する必要がありますか?またはトランザクションではない?いずれにしても、テーブルのデザインが貧弱なので、飛行しているレンガがなぜ飛行しなかったかについての詳細を尋ねるようなものです。 – Schwern

関連する問題