Индексирование SQL заставило некоторые запросы занять больше времени. Зачем? - PullRequest
0 голосов
/ 10 января 2019

Я создал базу данных, в которой хранится около 24 миллионов записей о продажах домов в Великобритании. Я написал небольшую Java-программу, которая запрашивает базу данных и отображает результаты в виде таблицы. Пользователь ищет почтовый индекс или частичный почтовый индекс, и отображаются все совпадения. Первоначально я работал над неиндексированной таблицей, и полные почтовые индексы (например, lk4 5th) заняли около 5 секунд. большие запросы (например, lk4 5) заняли около 8 секунд, а очень большие запросы (l) - около 25 секунд. Меня попросили проиндексировать базу данных, так как это увеличило бы скорость запросов. Я переделал таблицу со следующим кодом SQL:

CREATE TABLE sales(
id TEXT,price INTEGER,sale_date TEXT,postcode TEXT,
prop_type CHAR,newbuild CHAR,leasetype CHAR,
paon TEXT,saon TEXT,street TEXT,locality TEXT,
town TEXT,district TEXT,county TEXT,category CHAR,status CHAR
);
.mode csv
.import C:/Users/(path goes here)
CREATE INDEX i_postcode ON sales(postcode collate nocase);

Это значительно улучшило скорость поиска, который дает меньше результатов (например, lk4 5th - lk4), однако для более крупных поисков он увеличил его до неиспользованного количества времени. 5 минут +.

Единственный выполняемый запрос - очень простой запрос:

SELECT price, sale_date, postcode, paon, street, locality FROM sales WHERE postcode LIKE ?;

Я использовал Javas built в VisualVM software для просмотра выборок ЦП, и кажется, что org.sqlite.core.NativeDB.step[native] - это область концентрации, на обработку которой уходит так много времени. Я совершенно новичок в использовании баз данных и не смог найти в Интернете ничего, что бы указывало на то, что это должно было увеличить время обработки. Если у вас есть какие-либо идеи о том, что я могу сделать для увеличения скорости больших поисков, это будет очень цениться.

Я ценю ваше время.

1 Ответ

0 голосов
/ 10 января 2019

Я полагаю, что проблема вполне может заключаться в том, что почтовый индекс - это не то, что считается высокой мощностью, особенно когда фиксированная часть (до подстановочного знака) короче (более длинный поиск / больше результатов) и, таким образом, при этих более длительных поисках двоичный поиск становится 0 (n) линейным сканированием.

Я никогда не пробовал, но если длина фиксированной части аргумента поиска меньше 3 (так что l%, lk%, но не lk4%), тогда использование + почтовый индекс подойдет линейное сканирование более эффективного rowid , т. е. + почтовый индекс говорит о том, что пользователь не использует индекс.

  • длина 3 при условии, что lk4 в порядке

Ниже показан почтовый индекс, возвращающийся к rowid SCAN с кодированным + : -

DROP INDEX IF EXISTS i_postcode;
CREATE TABLE IF NOT EXISTS sales(
id TEXT,price INTEGER,sale_date TEXT,postcode TEXT,
prop_type CHAR,newbuild CHAR,leasetype CHAR,
paon TEXT,saon TEXT,street TEXT,locality TEXT,
town TEXT,district TEXT,county TEXT,category CHAR,status CHAR
);
EXPLAIN QUERY PLAN 
SELECT price, sale_date, postcode, paon, street, locality FROM sales WHERE postcode LIKE 's%';
CREATE INDEX  IF NOT EXISTS i_postcode ON sales(postcode collate nocase);
EXPLAIN QUERY PLAN 
SELECT price, sale_date, postcode, paon, street, locality FROM sales WHERE +postcode LIKE 's%';
EXPLAIN QUERY PLAN 
SELECT price, sale_date, postcode, paon, street, locality FROM sales WHERE postcode LIKE 's%';

Результат 1 - без индекса

enter image description here

Результат 2 - Индекс вынужден не использоваться (аналогично результату 1)

enter image description here

Результат 3 - + не используется, поэтому индекс используется

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...