2011-01-07 6 views
0

私はPythonで数値シミュレーションを行っており、非常に大きなデータオブジェクト(約200 MB)になっています。私はそれらをsqlite3 dbに書き込みます。解像度を上げた後(つまりデータサイズを約20%)、dbに挿入しようとするとメモリエラーが発生します。以前は小さな解像度でうまくいきました。ここでは、コードスニペットです:Pythonで大きな要素をsqlite3に挿入するdb - memory error

def write_to_db(self, filename, dataObject, name) : 
    connection = sqlite.connect(filename) 
    cursor  = connection.cursor() 
    cursor.execute("CREATE TABLE pulses (ID INTEGER PRIMARY KEY, name STRING, data BLOB)") 
    cursor.execute("INSERT INTO pulses(name, data) VALUES (?, ?)", (dataObjectName, sqlite.Binary(pickle.dumps(dataObject)))) 
    connection.commit() 
    connection.close() 

私はWinXPの、1GBのRAM、3ギガバイトのスワップ(および拡張する必要性を入れ替える窓-通知を受け取っていない)、Pythonの2.6の下で働いています。

ご協力いただきありがとうございます。 Tim

+0

SQLiteとほとんどのリレーショナルデータベースは、200 MBのオブジェクトを念頭に置いて設計されていません。それがうまくいっても、ひどいデータベースの断片化を引き起こす可能性があります。私は仕事のために間違ったツールを使用していると思います。 –

+0

ここでは、オブジェクトの酸洗いが問題と思われます。しかし、あなたが私にSQLiteが間違った選択であると言えば、おそらく別のアプローチを試みるべきです。しかし、どちら? – Tim

答えて

1

XPはスワップを少しずつ増やすだけです。あなたのプログラムが突然より多くのメモリを使用しようとし、スワップが不十分であれば、メモリエラーが発生します。

SQLiteは、1GBまでの大きさのブロブでかなりうまく動作します。通常、2GBを使用できます。ただし、32ビットプロセスではアドレス空間が使い果たされます。

大きいデータをファイルに格納してからデータベースに格納することをお勧めしますが、それはより効果的です。

次の操作を実行して、あなたの当面の問題を解決することができます:

  • スイッチを64ビットを使用します。マイクロソフトは、Windows 7ファミリパックを販売しています。これにはXP/Vistaの3つのインスタンスを$ 150(ストリート価格$ 130)でアップグレードして、複数のマシンをアップグレードすることができます。この方法で32ビットXPから64ビットWin 7に切り替えることができます。

  • pickleコールに-1を加えて、asciiのデフォルトではなくバイナリを使用する最新のpickleプロトコルを使用するように指示します。エンコーディング。結果としてデータが少なくなります。プロトコルのバージョンとそれらをサポートするPythonバージョンの詳細については、ドキュメントを読んでください。 (例えばbz2.compress(pickle.dumps OBJ、-1)

あなたがここに持っている問題の原因として最も可能性が高いが、アドレス空間が不足している32 -

  • も漬けデータを圧縮します。通常は2GBのデータだけを同時に処理することができ、さまざまな実行可能ファイルや共有ライブラリ、スレッドごとのスタック、SQLiteキャッシュなどもその領域から差し引かれます。積極的にデータを処理したときにdelとgc.collect()を呼び出すと、使用中の同時データ量が削減されます。

  • 0

    可能な代替ストレージメカニズムについては、コメントで尋ねます。保存しているデータが使用可能なRAMの5分の1の場合は、RAMを使い果たす前にデータをコピーすることができないため、メモリを非常に慎重に管理する必要があると言います。とにかくあなたはパフォーマンスを殺すだろう。潜在的に大きいと予想されるため、sqliteにBLOBを使用して適切な処理をさせることができます。

    sqliteを単純なキー/値ストアとして使用しているようです。フラットファイルの使用を検討しましたか? ATOMicityが必要な場合でも、sqliteデータベースを使用して、フラットファイルストア内のどのファイルが有効であるかを定義することができます。すべてのフラットファイルをきれいに書き込んだ後にのみDBにコミットし、DB内の対応する削除をコミットした後にフラットファイルを削除することで、安全に行うことができます。

    この作業を行うには、dataObjectをPythonのファイルタイプオブジェクトにシリアライズするためのメカニズムが必要です。 Pickleは、ファイルタイプのオブジェクトを渡すとこれを行うことができますが、それでもかなり効率が悪いと思われます。

    数値シミュレーションを実行しているとします。あなたは気が気になりませんか? numpy配列は、酸洗よりも効率的なtofile関数をサポートしています。あなたがまだそれを使用していない場合は、シミュレーションで大幅なパフォーマンスの向上が見込まれます。

    関連する問題