私は非常に大きなデータベースを持っています - 私は350m行のサブセットで作業していますが、最終的に約3b行になります。私のここでの目標は、このデータベースの特定のタイプのクエリを最適化することです。ただし、メモリ以外のほとんどすべてを犠牲にしています。私が今作業しているdbファイルは、PyTablesバージョン2.3.1でレベル1のbloscで圧縮されています。各行は13個のエントリを持っている - 一般的なエントリは次のようになります。pytablesで複雑なtable.where()クエリを最適化しますか?
['179', '0', '1', '51865852', '51908076', '42224', '22', '2', '20', '22', '2', '0.0516910530103', '0.0511359922511']
彼らは必ずしも同じタイプのすべての数値ではなくね。私は現在、この定義で、PyTables表に格納しています:
ind = tables.UInt16Col(pos=0)
hap = tables.UInt8Col(pos=1)
chrom = tables.UInt8Col(pos=2)
hap_start = tables.Int32Col(pos=3)
hap_end = tables.Int32Col(pos=4)
hap_len = tables.Int16Col(pos=5)
mh_sites = tables.Int16Col(pos=6)
mh_alt = tables.Int16Col(pos=7)
mh_n_ref = tables.Int16Col(pos=8)
all_sites = tables.Int16Col(pos=9)
all_alt = tables.Int16Col(pos=10)
freq = tables.Float32Col(pos=11)
std_dev = tables.Float32Col(pos=12)
私は本当にそれがこのデータベースを設定するために要する時間を気にしない - 私は最終的にちょうどアクセスし、一度、それを作成することがありますそれ。クエリの形式は次のとおりです。
a = [ x[:] for x in hap_table.where('''(mh_sites == 15) & (hap_len > 25000) & (hap_len < 30000) & (freq > .38) & (freq < .4) & (std_dev > .3) & (std_dev < .4)''')]
基本的には、特定の許容値を超える特定の行に一致するエントリを検索しています。私は事前にインデックスをいない場合
byteorder := 'little'
chunkshape := (32768,)
autoIndex := True
colindexes := {
"hap_len": Index(6, medium, shuffle, zlib(1)).is_CSI=False,
"freq": Index(6, medium, shuffle, zlib(1)).is_CSI=False,
"std_dev": Index(6, medium, shuffle, zlib(1)).is_CSI=False,
"mh_sites": Index(6, medium, shuffle, zlib(1)).is_CSI=False}
と10秒:私は上の検索だ4つのすべての列をインデックス化した場合、私の小さなデータベース(350メートル行)で、そのクエリは38秒かかります。私は、なぜクエリがインデックスデータベースの速度が遅いのかわかりません。おそらくインデックス作成では必要ないオーバーヘッドが発生するでしょうか?
私の目標は、このタイプのクエリを可能な限り最適化することです。基本的にはメモリ使用量以外のすべてを犠牲にしています(約2Gを使用したいと思っています。 5G)。私はインデックスを作成しようとしましたが、うまくいかないようです。すべてのクエリはmh_sitesの単一の値であり、可能な値は100個しかないので、複数のテーブルに分割することを考えました。したがって、私はいつでもデータのサブセットを検索しています(ただし、 mydata.root.table_1、mydata.root.table_2など)以外の方法を完全にはわかりません。私はまた、代わりに配列として格納しようと思った - おそらく浮動小数点型の配列、そして私はそれらを使用する必要があるときにintに他のすべてを変換する?違いがある場合は、通常20kから500kの結果が返されます。
このクエリの最適化についてのご意見はありますか?
データセットがあまりにも大きくソートされた場合は、追加する前に必ずソートする必要はありません。その場合、CSI索引を作成し、次にsortbyキーワードを使用して表をコピーします。このキーワードは、メモリー内に完全なデータセットを持つことなく、正しい順序で行を配置します。ソートされた方法でセットをコピーするには時間がかかるため、時間が問題になる可能性があります。しかし、あなたが一度書くと頻繁にクエリを行うシナリオでは、面倒なことに価値があるかもしれません。 –
これはPyTablesのドキュメントでも言及されています:[最適化 - 究極の速度を達成する:ソートされたテーブルとそれ以降](http://www.pytables.org/usersguide/optimization.html#achieving-ultimate-speed-sorted-tables-and) -超えて) – 153957