2013-07-31 5 views
4

Я должен обрабатывать словарь с 7 миллионами ключей (количество ключей в конечном итоге может составлять до 50 миллионов). Поскольку у меня осталось достаточно бара, чтобы сохранить его в памяти, я решил его сохранить.Хранение словаря на языке 7 миллионов слов в базе данных

Мой словарь выглядит следующим образом:

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

Сначала я попытался сохранить его в SQLite базы данных, используя sqlite3. Время, необходимое для его хранения, в порядке (примерно 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 для ускорения моих запросов? –

Смежные вопросы