2016-01-09 2 views
0

В настоящее время я изучаю SQLite (называемый Python).Ускорение запроса SQLite

Согласно моему предыдущему вопросу (Reorganising Data in SQLLIte), я хочу хранить несколько временных рядов (данные обучения) в моей базе данных.
я определил следующие поля:

CREATE TABLE VARLIST 
(
    VarID INTEGER PRIMARY KEY AUTOINCREMENT, 
    name TEXT UNIQUE NOT NULL 
)  

CREATE TABLE DATAPOINTS 
(
    DataID INTEGER PRIMARY KEY, 
    timeID INTEGER, 
    VarID INTEGER, 
    value REAL 
) 

CREATE TABLE TIMESTAMPS 
(
    timeID INTEGER PRIMARY KEY AUTOINCREMENT, 
    TRAININGS_ID INT, 
    TRAINING_TIME_SECONDS FLOAT 
) 

VARLIST имеет 8 записей, TIMESTAMPS записи 1e5 и DATAPOINTS вокруг 5e6.

Когда я теперь хочу, чтобы извлечь данные для данного TrainingsID и VarID, я пытаюсь это нравится:

SELECT    
    (SELECT TIMESTAMPS.TRAINING_TIME_SECONDS 
    FROM TIMESTAMPS 
    WHERE t.timeID = timeID) AS TRAINING_TIME_SECONDS, 
    (SELECT value 
    FROM DATAPOINTS 
    WHERE DATAPOINTS.timeID = t.timeID and DATAPOINTS.VarID = 2) as value 
FROM 
    (SELECT timeID 
    FROM TIMESTAMPS 
    WHERE TRAININGS_ID = 96) as t; 

EXPLAIN QUERY PLAN Команда обеспечивает:

0|0|0|SCAN TABLE TIMESTAMPS 
0|0|0|EXECUTE CORRELATED SCALAR SUBQUERY 1 
1|0|0|SEARCH TABLE TIMESTAMPS USING INTEGER PRIMARY KEY (rowid=?) 
0|0|0|EXECUTE CORRELATED SCALAR SUBQUERY 2 
2|0|0|SCAN TABLE DATAPOINTS 

Это в основном работает.
Но есть две проблемы:

  1. Minor проблема: Если есть timeID, где нет данных для запрошенной VarID is availabe, I get an line with the value None`.
    Я бы предпочел пропустить эту строку.

  2. Большая проблема: поиск невероятно медленный (приблизительно 5 минут с использованием http://sqlitebrowser.org/).

Как лучше всего улучшить производительность?
Есть ли лучшие способы сформулировать команду SELECT или изменить структуру базы данных?

+0

Похоже, вы делаете крест-соединение. Обычно они довольно медленны для наборов данных указанного вами размера. –

+0

Может ли это помочь в производительности, если я реструктурирую базу данных так, чтобы данные из «временных меток» напрямую отображались в «datapoints»? (мой первоначальный десициб, чтобы разделить его на 2 таблицы, был главным образом обусловлен уменьшением размера данных. Это имеет меньшее значение, чем производительность). – BerndGit

+1

Показывает результат работы [РАЗМЕРЫ ЗАПРОСА] (http://www.sqlite.org/eqp. HTML). –

ответ

1

Ok, на основе подсказок я получил я мог экстремально ускорить поиск по applieng INDEXES как:

CREATE INDEX IF NOT EXISTS DP_Index on DATAPOINTS (VarID,timeID,DataID); 
CREATE INDEX IF NOT EXISTS TS_Index on TIMESTAMPS(TRAININGS_ID,timeID); 

EXPLAIN QUERY PLAN выход теперь звучит как:

0|0|0|SEARCH TABLE TIMESTAMPS USING COVERING INDEX TS_Index (TRAININGS_ID=?) 
0|0|0|EXECUTE CORRELATED SCALAR SUBQUERY 1 
1|0|0|SEARCH TABLE TIMESTAMPS USING INTEGER PRIMARY KEY (rowid=?) 
0|0|0|EXECUTE CORRELATED SCALAR SUBQUERY 2 
2|0|0|SEARCH TABLE DATAPOINTS USING INDEX DP_Index (VarID=? AND timeID=?) 

Спасибо за ваши комментарии.

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