567行と16,382列のファイルが1つあり、そのほとんどが浮動小数点数です。 117,493行で3列しかない別のファイルがあります。内容は生物学と遺伝学を扱っています。
ファイル内の数値の意味がわかりません。これは大学のプロジェクトで、ファイルの内容がわからなくても、ファイルを指定してさまざまなことを照会できる必要があります。内容を理解する必要があるため、データを正規化することは想定されていません。パフォーマンスと、どのデータベースを選択するかという理由で評価されます。
ファイル1:(567行、16,382列)
このファイルの列の数に驚かされています。列は主に一連の数値を持つ遺伝情報であり、正規化できません。最初はPostgresqlがFile 1に適していると思っていましたが、それらは行指向のデータベースであるため、恐ろしいでしょう。私はCassandraが列指向のルックアップに適していることを読みましたが、問題はほとんどの列と行にデータが含まれており、値のないいくつかの領域を除いて、ほとんどが構造化されています。 Cassandraを使用する方が良いでしょうか?
ファイル1の操作:
平均や標準偏差の計算などの集計関数について、SQLとNoSQLの間の一般的なパフォーマンスを確認できません。これは私のデータベースを選択するもう1つの要因です。 Cassandraは列指向であるため、ここではPostgresqlよりCassandraの方が高速だと思います。
ファイル2:(117,493行、3列)
すべての行と列にはデータが含まれています。 3列しかありませんが117,493行あり、Postgresqlは行指向であり、欠落データがないため、Postgresqlはここで優れていると思います。この場合、より良いNoSQLの代替案はありますか? Key-ValueストアのNoSQLは主に取得に使用されるため、より良いでしょうか?
ファイル2の操作:
私が持っている大きなファイルのほとんどは、File 1やFile 2。 File 2にPostgresqlを使用し、File 1にCassandraを使用すると、かなりのパフォーマンスの損失がありますか?通常、関連するテーブルをRDMSに格納しますが、File 1の列数は、ハイブリッドアプローチを使用する方が良いという意味ですか?
@Dobobすべてを正規化できます:)それがあまり秘密でない場合、それはどのようなデータですか? (遺伝学者に転向したDBAとして尋ねる。)
これは全般的にtrueです。そして、どのように正規化できるかを検討することから始めるべきです。明らかに、あなたはその考えを嫌い、常に正常化することはできません。たとえば、ラスターは多くの場合、科学機器からの読み取り値のコレクションであり、実際に非正規化することはできません。それらは同時に取得され、同じサンプルを表し、多くの場合1,000のデータポイントを持ちます。 (ただし、PostGISに保存できます)。
PostgreSQLは テーブルの16,383列(または、1600 +以上) をサポートしていませんが、 SQL配列 はサポートしています。あなたはおそらくそれを利用することができます、
_CREATE TABLE foo AS
SELECT
r AS id,
array_agg(c) AS genetic_stuff
FROM generate_series(1,567)
AS r
CROSS JOIN LATERAL generate_series(1,16382)
AS c
GROUP BY r;
_
これで、最初の基準を満たしているものの、正気ではないテーブルができました。
_ Table "public.foo"
Column | Type | Modifiers
---------------+-----------+-----------
id | integer |
genetic_stuff | integer[] |
_
平均を見つけるのは簡単です。
_SELECT id, avg(x)
FROM foo
CROSS JOIN LATERAL unnest(genetic_stuff)
AS t(x)
GROUP BY id;
_
そして、その全体の操作について_Execution time: 3865.308 ms
_!それについて文句を言うことができます。その平均をキャッシュしたい場合は、自由に _MATERIALIZED VIEW
_ を使用してください。
標準偏差の場合は 適切な集約関数を使用avg()
の代わりに使用します。実行時間はほぼ同じです。
ここでこれをどのようにクエリしているかはわかりませんが、インデックスがない場合(最悪の場合)は非常にシンプルで高速です(seqスキャンであることを考慮してください)、16,000のアイテムを含むアレイのスキャンは、最新のCPU、およびPostgreSQL 9.6では、このseqスキャンは並行して実行することもできます(afaik)。
_SELECT * FROM foo
WHERE genetic_stuff @> ARRAY[5];
_
インデックスを使用できますか?承知しました。 intarray
モジュールから、
2つのGistインデックス演算子クラスが提供されています。Gist__int_ops(デフォルトで使用)は、中小規模のデータセットに適していますが、Gist__intbig_opsは、より大きな署名を使用し、大きなデータセットのインデックス作成に適しています。 (つまり、多数の個別の配列値を含む列)。実装では、非可逆圧縮が組み込まれたRDツリーデータ構造が使用されます。
それを試してみましょう...
_CREATE INDEX ON foo
USING Gist(genetic_stuff Gist__intbig_ops);
VACUUM FULL foo;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------
Index Scan using foo_genetic_stuff_idx on foo (cost=0.14..8.16 rows=1 width=22) (actual time=0.119..47.846 rows=567 loops=1)
Index Cond: (genetic_stuff @> '{5}'::integer[])
Planning time: 0.072 ms
Execution time: 47.948 ms
(4 rows)
_
インデックススキャン以外に何が必要かわからない。すべての行に_5
_の要素が含まれていない場合は、おそらくより有用ですが、それはサンプルデータにすぎません。
とにかくそれを持っています。
その恥ずかしがり屋ですが、PG行は太っているので、他のことは少しオーバーヘッドの問題にはなりませんが、多くの行を話しているわけではなく、最終的には、以下の表で基準が5088 kBのみであることは問題になりません私のシステム。自分を心配する価値はほとんどありません。
_CREATE TABLE baz
AS
SELECT
x AS id,
x*2 AS x2,
x*3 AS x3,
x*4 AS x4
FROM generate_series(1,117493)
AS t(x);
_