Производительность индекса SQLite - PullRequest
0 голосов
/ 13 июня 2018

У меня есть таблица в следующем формате

email, item_id, json, где

  • email - строка
  • item_id - метка времени Unix вмс
  • json - это данные элемента, которые будут использоваться с расширением JSON1

, и у меня также есть многоколонный индекс для этой таблицы с email, id

Я выполняю много запросов в стиле WHERE email = 'asd' AND item_id > ... AND item_id < ...

Я работаю с MongoDB уже слишком много лет, поэтому я привык не иметь дело с нормализацией базы данных, а просто пошел ссамый простой макет таблицы SQL.

На телефоне запрос для вышеупомянутого стиля может занять до секунды для запроса 35000 элементов.Индекс действительно используется.

Получу ли я заметное повышение производительности, когда нормализую базу данных, создав новую таблицу с email, email_id, изменив оригинал на email_id, item_id, json и начав запросы через JOINS?В этом случае email, email_id будет содержать около 2-5 единиц и email_id, item_id, json много тысяч.

1 Ответ

0 голосов
/ 13 июня 2018

Использование 3 проверяет оригинал, запрос с использованием JOIN и дополнительную опцию, используя подзапрос, а не объединение, чтобы получить идентификатор электронной почты на основе адреса электронной почты и сравнить его с email_id.Подзапрос вышел на первое место, исходный худший.

Результаты были: -

SELECT * FROM original WHERE email = 'email3@ouremail.com' AND item_id > 7800 AND item_id < 2404327029516376406

ОК Время: 0,199 с

SELECT * FROM item WHERE email_id = (SELECT email.email_id FROM email WHERE email.email = 'email3@ouremail.com') AND item_id > 7800 AND item_id < 2404327029516376406

ОК Время: 0,082 с

SELECT * FROM item JOIN email ON item.email_id = email.email_id WHERE email.email = 'email3@ouremail.com' AND item_id > 7800 AND item_id < 2404327029516376406

ОК Время: 0,109 с

Для создания и проверки использовалось следующее: -

DROP TABLE IF EXISTS original;
CREATE TABLE IF NOT EXISTS original (email TEXT, item_id INTEGER, json BLOB, PRIMARY KEY(email,item_id));
WITH RECURSIVE cnt(x,y,z) 
AS (
    SELECT 'email'||(1 + ABS(random() / (9223372036854775807 / 5)))||'@ouremail.com',
                ABS(random()),
          randomblob(ABS(random() / (9223372036854775807 / 40) ))
            UNION ALL SELECT 
              'email'||(1 + ABS(random() / (9223372036854775807 / 5)))||'@ouremail.com',
                ABS(random()),
                randomblob(ABS(random() / (9223372036854775807 / 40)))  
            FROM cnt LIMIT 350000
)
INSERT INTO original SELECT * FROM cnt;


DROP TABLE IF EXISTS email;
CREATE TABLE IF NOT EXISTS email (email_id INTEGER PRIMARY KEY, email TEXT);
INSERT INTO email SELECT DISTINCT null,email FROM original;


DROP TABLE IF EXISTS item;
CREATE TABLE IF NOT EXISTS item (email_id, item_id, json);
INSERT INTO item SELECT 
    (SELECT email_id FROM email WHERE original.email = email.email),
        item_id,
        json FROM original;


SELECT * FROM original WHERE email = 'email3@ouremail.com' AND item_id > 7800 AND item_id < 2404327029516376406;
SELECT * FROM item WHERE email_id = (SELECT email.email_id FROM email WHERE email.email = 'email3@ouremail.com') AND item_id > 7800 AND item_id < 2404327029516376406; 
SELECT * FROM item JOIN email ON item.email_id = email.email_id WHERE email.email = 'email3@ouremail.com' AND item_id > 7800 AND item_id < 2404327029516376406;

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

EXPLAIN QUERY PLAN SELECT * FROM original WHERE email = 'email3@ouremail.com' AND item_id > 7800 AND item_id < 2404327029516376406;
EXPLAIN QUERY PLAN SELECT * FROM item WHERE email_id = (SELECT email.email_id FROM email WHERE email.email = 'email3@ouremail.com') AND item_id > 7800 AND item_id < 2404327029516376406;
EXPLAIN QUERY PLAN SELECT * FROM item JOIN email ON item.email_id = email.email_id WHERE email.email = 'email3@ouremail.com' AND item_id > 7800 AND item_id < 2404327029516376406;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...