Моя проблема в том, что мои запросы слишком медленные.
У меня довольно большая база данных sqlite.Таблица:
CREATE TABLE results (
timestamp TEXT,
name TEXT,
result float,
)
(я знаю, что временные метки как TEXT не оптимальны, но, пожалуйста, игнорируйте это для целей этого вопроса. Я должен исправить это, когда у меня будет время)
«имя» - это категория.Это вычисление содержит результаты вычисления, которое должно быть сделано в каждой отметке времени для всех «имен».Таким образом, вставки выполняются с одинаковыми временными метками, но запросы будут выполняться с одинаковыми именами (то есть, я хочу дать имя, получить его временной ряд), например:
SELECT timestamp,result WHERE name='some_name';
Теперь, как яЯ делаю вещи сейчас, чтобы не иметь индексов, рассчитать все результаты, а затем создать индекс на имя CREATE INDEX index_name ON results (name)
.Причина в том, что мне не нужен индекс при вставке, но наличие индекса сделает запросы на индекс очень быстрыми.
Но это не так.База данных довольно большая.У него около полумиллиона меток времени, и для каждой метки времени у меня есть около 1000 имен.
Я подозреваю, хотя я не уверен, что причина в том, что это медленно, в том, что все, хотя я проиндексировал именаони все еще разбросаны по всему физическому диску.Что-то вроде:
timestamp1,name1,result
timestamp1,name2,result
timestamp1,name3,result
...
timestamp1,name999,result
timestamp1,name1000,result
timestamp2,name1,result
timestamp2,name2,result
etc...
Я уверен, что запрос с NAME = 'some_name' медленнее, чем если бы строки были физически упорядочены как:
timestamp1,name1,result
timestamp2,name1,result
timestamp3,name1,result
...
timestamp499997,name1000,result
timestamp499998,name1000,result
timestamp499999,name1000,result
timestamp500000,namee1000,result
etc...
Итак, как мне это сделать?скажите SQLite, что порядок, в котором я бы хотел, чтобы строки на диске были не тем, в котором они были записаны?
ОБНОВЛЕНИЕ: я также убежден, что медлительность выбора с таким индексом возникаетисключительно от несмежного доступа к диску.Выполнение SELECT * FROM results WHERE name=<something_that_doesnt_exist>
немедленно возвращает ноль результатов.Это говорит о том, что он не находит медленные имена, а читает их с диска.