数学的な文脈からスパース行列を考えていると仮定します: http://en.wikipedia。 org / wiki / Sparse_matrix (ここで説明されている保存手法は、永続ストレージ(ディスク使用量が少ない)ではなく、メモリストレージ(高速算術演算)用です。)
通常、サーバー側ではなくクライアント側でこのマトリックスを操作するため、SQL-ARRAY []が最適です!
問題は、マトリックスの希薄性をどのように活用するかです。ここにいくつかの調査の結果があります。
セットアップ:
- Postgres 8.4
- 倍精度(8バイト)の400*400要素のマトリックス->マトリックスあたり1.28MiBのrawサイズ
- 33%の非ゼロ要素->行列あたり427kiBの有効サイズ
- 約1000の異なるランダムに入力された行列を使用して平均化
競合する方法:
- 自動に依存する サーバー側の圧縮 SETSTORAGEMAINまたはEXTENDEDの列の数。
- ゼロ以外の要素とビットマップのみを保存します (
bit varying(xx)
)マトリックス内のゼロ以外の要素を配置する場所を記述します。 (1つの倍精度は1ビットの64倍です。理論的には(オーバーヘッドを無視して)<=98%がゼロ以外の場合、この方法は改善されるはずです;-))サーバー側の圧縮がアクティブになります。 - 交換 行列のゼロはNULLで 。 (RDBMSはNULLの保存に非常に効果的です。)サーバー側の圧縮がアクティブ化されます。
(2番目のインデックスを使用したゼロ以外の要素のインデックス付け-ARRAY []はあまり有望ではないため、テストされていません。)
結果:
- 自動圧縮
- 追加の実装作業はありません
- ネットワークトラフィックの減少はありません
- 最小限の圧縮オーバーヘッド
- 永続ストレージ=生のサイズの39%
- ビットマップ
- 許容できる実装作業
- ネットワークトラフィックがわずかに減少しました。スパース性に依存
- 永続ストレージ=生のサイズの33.9%
- ゼロをNULLに置き換えます
- いくつかの実装作業(APIは、INSERTクエリの作成中にARRAY []のどこにどのようにNULLを設定するかを知る必要があります)
- ネットワークトラフィックに変化はありません
- 永続ストレージ=生のサイズの35%
結論:EXTENDED/MAINストレージパラメータから始めます。暇な場合は、データを調査し、スパースレベルで私のテストセットアップを使用してください。ただし、効果は予想よりも低い場合があります。
マトリックスのシリアル化(行優先順位など)に加えて、マトリックスの次元NxMに2つの整数列を常に使用することをお勧めします。ほとんどのAPIはテキストSQLを使用するため、ネストされた「ARRAY [ARRAY [..]、ARRAY [..]、ARRAY [..]、ARRAY [..]、..]」のネットワークトラフィックとクライアントメモリを大幅に節約できます。 !!!
テバス
CREATE TABLE _testschema.matrix_dense
(
matdata double precision[]
);
ALTER TABLE _testschema.matrix_dense ALTER COLUMN matdata SET STORAGE EXTERN;
CREATE TABLE _testschema.matrix_sparse_autocompressed
(
matdata double precision[]
);
CREATE TABLE _testschema.matrix_sparse_bitmap
(
matdata double precision[]
bitmap bit varying(8000000)
);
すべてのテーブルに同じ行列を挿入します。具体的なデータは特定のテーブルによって異なります。未使用であるが割り当てられたページのためにサーバー側のデータを変更しないでください。またはVACUUMを実行します。
SELECT
pg_total_relation_size('_testschema.matrix_dense') AS dense,
pg_total_relation_size('_testschema.matrix_sparse_autocompressed') AS autocompressed,
pg_total_relation_size('_testschema.matrix_sparse_bitmap') AS bitmap;