Я должен обрабатывать словарь с 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 обновить свой словарь в полку ...
Я не хочу, чтобы мариновать мой словарь, так как это означает, что я должен загрузить весь словарь, если я хочу использовать его позже.
Есть ли способ улучшить один из этих двух методов, чтобы иметь лучшее время доступа/время загрузки?
Благодарим за помощь!
Можете ли вы подробно рассказать о том, почему я должен выбирать int1 и int2 для ускорения моих запросов? –