2013-07-31 70 views
4

我必须处理一个7百万个密钥字典(密钥的数量最终可能高达〜50百万)。由于我没有足够的内存来保存它,所以我决定存储它。在数据库中存储700万个密钥的python字典

我的字典里是这样的:

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 

但后来,我需要使用这个存储的词典,以获取一定的价值,但每个选择似乎需要大约1.5秒。因为我需要访问大约一百万值是令人沮丧:

>>>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 

所以,即使我不喜欢这样一个几百万的请求,时间的总量应该在秒的百左右。

但是出现了一个新问题,现在将我的字典存放在书架上所需的时间并不满足我。

>>> 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 

一个人必须加入到这个数额,前者键(这是元组)转换为字符串所需要的时间额外的时间。使用再版:

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

这导致目前共有566.332387924来更新我的字典成货架...

我不想咸菜我的字典里,因为它意味着我将不得不加载整个字典,如果我想以后使用它。

有没有什么办法可以改善这两种方法之一,以便有更好的访问时间/加载时间?

感谢您的帮助!

回答

3

对于像这样的大型表上的查询要快速返回,您需要索引相关列。在你的情况下,我会添加这个作为主键。

create table test (
    Int1 integer, 
    Int2 integer, 
    Int3 integer, 
    Primary key (int1, int2) 
) 
+0

你能详细解释为什么我应该选择int1和int2来加快我的查询吗? –

相关问题