4

我必须处理一个 700 万键的字典(键的数量最终可以达到 ~5000 万)。由于我几乎没有足够的内存来保存它,所以我决定存储它。

我的字典是这样的:

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 秒。由于我需要访问大约一百万个值,因此令人沮丧:

>>>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 来将我的字典更新到书架上......

我不想腌制我的字典,因为这意味着如果我以后想使用它,我必须加载整个字典。

有什么方法可以改进这两种方法中的一种,以获得更好的访问时间/加载时间?

谢谢你的帮助 !

4

1 回答 1

3

对于像这样的大表查询要快速返回,您需要为相关列建立索引。在您的情况下,我会将其添加为主键。

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