4

700 万個のキー辞書を処理する必要があります (キーの数は、最終的に最大 5000 万個になる可能性があります)。メモリに保持するのに十分な RAM がないため、保存することにしました。

私の辞書は次のようになります。

dictionary={(int1,int2):int3,...}

最初に、sqlite3 を使用して sqlite データベースに保存しようとしました。保存に必要な時間は問題ありません (約 70 秒)。使用timeit:

>>>import sqlite3
>>>conn=sqlite3.connect('test_sqlite.sqlite')
>>>c=conn.cursor()
>>>c.execute('create table test (int1 int, int2 int, int3 int)')
>>>conn.commit()
>>>conn.close()
>>>import timeit
>>>timeit.timeit('c.executemany("insert into test values (?,?,?)",((key[0],key[1],dictionary[key]) for key in dictionary.iterkeys())),setup='import sqlite3;conn=sqlite3.connect("test_sqlite.sqlite");c=conn.cursor();dictionary={(i,i+1):i+2 for i in xrange(7000000)}',number=1)
70.7033872604

しかし、特定の値を取得するためにこの保存された辞書を使用する必要がありますが、各 SELECT には約 1.5 秒かかるようです。約 100 万の値にアクセスする必要があるため、落胆しています。

>>>timeit.timeit('c.execute("select id1 from test where id2=={}".format(value)).fetchone()[0]',setup=import sqlite3;conn=sqlite3.connect("test_sqlite.sqlite");c=conn.cursor();value=5555',number=1)
1.5300869941711426

次に、棚にある辞書を更新しようとしました。これで、棚上げされた辞書で値を取得するのにかなりの時間がかかりました。

>>> timeit.timeit('a=f[key]',setup='import shelve;f=shelve.open("test_timeit","r");key="1000"',number=10000)
0.320019006729126

したがって、このような数百万のリクエストを行ったとしても、合計時間は約 100 秒になるはずです。

しかし、新しい問題が発生しました。今のところ、辞書を棚に保管するのに必要な時間では満足できません。

>>> timeit.timeit('f.update(dictio)',setup='import shelve;f=shelve.open("test_timeit","c");dictio={"({},{})".format(i,i+1):i+2 for i in xrange(7000000)}',number=1)
504.728841782

この量に、以前のキー (タプル) を文字列に変換するために必要な余分な時間を追加する必要があります。repr の使用:

>>>timeit.timeit('repr.repr((1,2))',setup='import repr',number=7000000)
61.6035461426

私の辞書を棚に更新するには、合計で 566.332387924 になります...

後で使用したい場合、辞書全体をロードする必要があることを意味するため、辞書をピクルしたくありません。

アクセス時間/読み込み時間を改善するために、これら2つの方法のいずれかを改善する方法はありますか?

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

4

1 に答える 1

3

このような大規模なテーブルに対するクエリをすばやく返すには、関連する列にインデックスを付ける必要があります。あなたの場合、これを主キーとして追加します。

create table test (
    Int1 integer,
    Int2 integer,
    Int3 integer,
    Primary key (int1, int2)
)
于 2013-07-31T13:52:39.203 に答える