2012-05-02 6 views
2

В качестве ответа на мой вопрос: Is it normal that sqlite.fetchall() is so slow? кажется, что выборки и выборки могут быть невероятно медленными для sqlite.Как я могу ускорить получение результатов после запуска SQL-запроса?

Как я уже там, у меня есть следующий запрос:

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' 

Выполнение оператора выбора занимает около 50 секунд (приемлемо). Однако fetchall() занимает 788 секунд, только выборка результатов 981.

Способ, предложенный для ускорения запроса, заданного в качестве ответа на мой вопрос: Is it normal that sqlite.fetchall() is so slow? с использованием fetchmany(), не улучшил скорость получения результатов.

Как я могу ускорить получение результатов после запуска SQL-запроса?


СКП точно так, как я пытался выполнить его в командной строке:

sqlite> 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 = 1 
    ...> 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; 

обновление:

Так что я начал выполнение запроса на командной строке около 45 минут назад, и он все еще занят, поэтому он также очень медленно использует командную строку.

+0

Сколько времени тот же запрос, принимать при выполнении его через клиент? –

+0

Кроме того, какой модуль python sqlite3 вы используете? Какая версия? Что такое версия sqlite3, используемая модулем? –

+0

Я использую модуль sqlite: 2.6.3 и sqlite версия: 3.7.10. Я пытаюсь выполнить команду через диспетчер SQLite, но, похоже, не справляется с этим. –

ответ

1

От чтения this question, похоже, вы могли бы воспользоваться использованием APSW sqlite module. Как-то вы можете стать жертвой своего модуля sqlite, в результате чего ваш запрос будет выполнен менее эффективным образом.

Мне было любопытно, поэтому я попытался использовать apsw самостоятельно. Это было не слишком сложно. Почему бы вам не попробовать?

Чтобы установить его, я должен был:

  1. Извлечение latest version.
  2. Имейте установочный пакет, чтобы получить новейшее объединение в sqlite.

    python setup.py fetch --sqlite 
    
  3. Сборка и установка.

    sudo python setup.py install 
    
  4. Используйте его вместо другого модуля sqlite.

    import apsw 
    <...> 
    conn = apsw.Connection('foo.db')