2013-11-10 2 views
0

У меня есть таблица SQLite, которая составляет около 30 миллионов строк на 500 столбцов. Три из этих столбцов:Оптимизировать таблицу SQLite для двух разных поисков

CREATE TABLE core (
state TEXT, 
year INTEGER, 
randInt INTEGER, 
); 

Моя основная польза для этой таблицы является SELECT подмножеств, либо state - year парами или по сравнению с randInt. randInt является случайным числом, что в диапазоне от 0 до 100.

Примеры выбора состояния года:

SELECT * WHERE state='MA' AND year=1999; 
SELECT * WHERE (state='MA' AND year=1999) OR (state='NJ' AND year=1998); 

Примеры выбора randInt:

SELECT * WHERE randInt < 10; 
SELECT * WHERE randInt = 10; 

Эти два типа выборов содержат больше, чем 95% запросов к базе данных я буду делать. Есть ли способ оптимизировать таблицу специально для них?

Я предполагаю, что я хочу, чтобы явно CREATE INDEX для randInt и индекс соединения для state,year, но я не знаю, если они имеют одно мешает другому, и я не знаю, как создавать составные индексы.

Должен ли я отключать индексирование всех остальных 497 столбцов, так как я редко буду когда-либо индексировать их?

ответ

1

Создание индекса для одного столбца не влияет на другие индексы. Обратите внимание, однако, что SQLite использует не более одного индекса во время запроса (не проблема в вашем случае).

Кроме того, если вы не создали индексы для других столбцов 497, вам не нужно «индексировать их» для них. Индексы занимают пространство и требуют времени для обновления при обновлении таблицы, поэтому было бы катастрофой иметь 497 индексов, которые вам не нужны.

Чтобы создать индекс на две колонки, которые вы должны выполнить что-то вроде:

CREATE INDEX indyearstate ON tbl (year,state) 
+0

Насколько я понял, индексы создаются по умолчанию в SQLite. Я определенно мог ошибаться. Кроме того, если я могу иметь не более одного индекса, должен ли я создать комбинированный столбец состояния года (например, конкатенировать их вместе)? Я определенно хотел бы сделать это, если бы это ускорило 'SELECT' даже 10%. –

+0

Я думал об этом. Если вы планируете много запросов, я бы предложил иметь столбец в формате yearstate с целым числом, указывающим как год, так и состояние. Например (год * 100 + state_number). Индексирование этой переменной было бы очень просто для SQLite. –

+0

О, и индекс в двух столбцах по-прежнему является единственным индексом. Я просто сказал, что если у вас есть индекс для (год, состояние) и индекс для (randInd), то только один из них будет использоваться в любом запросе, а не в обоих. –

1

Вы должны создать два индекса:

CREATE INDEX IX_1 ON core(year, state); 
CREATE INDEX IX_2 ON core(randInt); 
ANALYZE; -- ask SQLite to analyze data and update "stats" table on indices 

С тех пор ваши запросы будут работать (значительно) быстрее, и вы не должен ничего делать для обновления индексов: SQLite будет поддерживать их в актуальном состоянии (до тех пор, пока вы вручную не сбросите индексы с помощью «DROP INDEX»).

Вы также можете попробовать этот индекс вместо IX_1:

CREATE INDEX IX_1a ON core(state, year); 

Если ваша основная таблица имеет несколько различных «состояния», то «года» этот показатель может ускорить вещи немного больше.

+0

+1 для ANALYZE. Более разные годы, чем на самом деле, поэтому я буду придерживаться '(year, state)'. –

+0

Как я понимаю, 'ANALYZE' полезно, только если вы запускаете запросы с' JOIN'. Не повредит. –

+0

ANALYZE помогает в любом запросе, который имеет условие WHERE, которое можно оптимизировать с помощью индекса. Даже если вы выберете одну таблицу без JOIN. – SqliteDog

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