Вопрос по performance, sqlite – Это нормально, что sqlite.fetchall () так медленно?

2

У меня есть 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'

Есть ли причина, по которой сборка занимает так много времени?

update

Выполнение:

while 1:
    info = self.cursor.fetchone()
    if info:
        <do something>
    else:
        break

идет так же медленно, как

allInfo = self.cursor.fetchall()         
for info in allInfo:
    <do something>
Я бы попытался перенести как можно больше строгих ограничений на равенство вINNER JOIN& APOS; sON пункт, потому что это (надеюсь) минимизирует размер кучи, поражающейWHERE раздел (неравенства обычно загружаются в память для полного сканирования кучи, и в этот момент шкала времени определяется размером кучи, а не индексом - это раздражает и, возможно, не интуитивно понятно, но в основном неизбежно из-за недетерминированной природы результата запроса неравенства размер). Nisan.H

Ваш Ответ

1   ответ
3

По умолчаниюfetchall() так медленно, как зацикливаниеfetchone() из-заarraysize изCursor объект устанавливается на 1.

Для ускорения вы можете зацикливатьсяfetchmany()но чтобы увидеть прирост производительности, вам нужно предоставить ему параметр размера больше 1, в противном случае он "извлечет" многие ". партиямиarraysizeто есть 1.

Вполне возможно, что вы можете получить прирост производительности, просто увеличив значение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#sqlite3.Cursor.fetchmany

Я принял это, потому что это ответило на мой вопрос, но я не могу заставить его ускорить использование fetchmany. Спасибо хоть. Niek de Klein

Похожие вопросы