Это нормально, что sqlite.fetchall() так медленно?
У меня есть SQL-запрос, который выбирает из двух внутренних объединенных таблиц. Выполнение оператора select занимает около 50 секунд. Однако fetchall() занимает 788 секунд и получает только 981 результат. Это код запроса и выборки:
time0 = time.time()
self.cursor.execute("SELECT spectrum_id, feature_table_id "+
"FROM spectrum AS s "+
"INNER JOIN feature AS f "+
"ON f.msrun_msrun_id = s.msrun_msrun_id "+
"INNER JOIN (SELECT feature_feature_table_id, min(rt) AS rtMin, max(rt) AS rtMax, min(mz) AS mzMin, max(mz) as mzMax "+
"FROM convexhull GROUP BY feature_feature_table_id) AS t "+
"ON t.feature_feature_table_id = f.feature_table_id "+
"WHERE s.msrun_msrun_id = ? "+
"AND s.scan_start_time >= t.rtMin "+
"AND s.scan_start_time <= t.rtMax "+
"AND base_peak_mz >= t.mzMin "+
"AND base_peak_mz <= t.mzMax", spectrumFeature_InputValues)
print 'query took:',time.time()-time0,'seconds'
time0 = time.time()
spectrumAndFeature_ids = self.cursor.fetchall()
print time.time()-time0,'seconds since to fetchall'
Есть ли причина, по которой сборка занимает так много времени?
Обновить
Выполнение:
while 1:
info = self.cursor.fetchone()
if info:
<do something>
else:
break
идет так же медленно, как
allInfo = self.cursor.fetchall()
for info in allInfo:
<do something>
2 ответа
По умолчанию fetchall()
так медленно, как зацикливание fetchone()
из-за arraysize
из Cursor
объект устанавливается на 1.
Чтобы ускорить процесс вы можете зациклить fetchmany()
, но чтобы увидеть прирост производительности, вам нужно предоставить ему параметр размера больше 1, иначе он получит "много" партиями arraysize
т.е.
Вполне возможно, что вы можете получить прирост производительности, просто увеличив значение arraysize
, но у меня нет опыта в этом, поэтому вы можете поэкспериментировать с этим, выполнив что-то вроде:
>>> import sqlite3
>>> conn = sqlite3.connect(":memory:")
>>> cu = conn.cursor()
>>> cu.arraysize
1
>>> cu.arraysize = 10
>>> cu.arraysize
10
Подробнее об этом здесь: http://docs.python.org/library/sqlite3.html
Если вы выполняете сложный запрос, попробуйте создать таблицу, используя этот сложный запрос, а затем выполните выборку в созданной таблице, чтобы производительность была хорошей.