БД SQLite выглядит отсортированной, но я вытащил строки не в порядке сортировки - PullRequest
0 голосов
/ 03 июня 2019

Мне сказали, когда вы используете .scheme, и он говорит это, это означает, что он отсортирован по этому индексу.enter image description here

Когда я вытягиваю строки, используя:

cursor.execute('SELECT * FROM DX WHERE studyid='+id)

, я получаю результаты, не отсортированные по этому идентификатору.Я знаю, что могу использовать ORDER BY, но я хочу, чтобы он работал быстрее, я хочу, чтобы сортировка сделала это для меня.

1 Ответ

3 голосов
/ 03 июня 2019

Без указания ORDER BY SQLite, скорее всего, будет использовать самый быстрый метод для возврата результатов, и это будет просмотр индекса rowid (который есть во всех таблицах, если в таблице нетбыл определен с использованием БЕЗ ROWID).Однако порядок будет в соответствии с этим индексом (вероятный порядок вставки).

rowid обычно является самым быстрым способом, которым SQLite может получить результаты.Однако, если вы введете ORDER BY, тогда он будет использовать индекс, который лучше всего подходит, и если индекс покрывает ORDER BY, это будет тот индекс.

Короче говоря, если вы хотите, чтобы данные были ORDERED, вы должны использоватьORDER BY.

Обратите внимание на следующее: -

DROP TABLE IF EXISTS DX;
CREATE TABLE IF NOT EXISTS DX (studyid);
EXPLAIN QUERY PLAN SELECT * FROM DX WHERE studyid = "x";
EXPLAIN QUERY PLAN SELECT * FROM DX WHERE studyid = "x" ORDER BY studyid;
CREATE INDEX IF NOT EXISTS DX_IX1 ON DX(studyid);
EXPLAIN QUERY PLAN SELECT * FROM DX WHERE studyid = "x" ORDER BY studyid;

Первый результат (без ORDER BY) показывает, что таблица сканируется (т. Е. С использованием rowid (встроенного B-дерева)): -

enter image description here

Второй результат (ORDER BY, но индекс не покрывает studyid) также сканирует таблицу через встроенное B-дерево: -

enter image description here

Третий результат, когда существует индекс в столбце Studyid, использует индекс studyid согласно: -

enter image description here

Если вы затем рассмотрите пример с разумным количеством данных (100000 строк), используя: -

DROP TABLE IF EXISTS DX;
DROP TABLE IF EXISTS DX2;
CREATE TABLE IF NOT EXISTS DX (studyid);
CREATE TABLE IF NOT EXISTS DX2 (studyid);
CREATE INDEX IF NOT EXISTS DX_IX1 ON DX2(studyid);
WITH RECURSIVE cte AS (SELECT abs(random() % 1000) UNION ALL SELECT abs(random() % 1000) FROM cte LIMIT 100000)
INSERT INTO DX SELECT * FROM cte;
INSERT INTO DX2 SELECT * FROM DX;


SELECT * FROM DX2 WHERE studyid > 1000;
SELECT * FROM DX WHERE studyid > 1000;

SELECT * FROM DX WHERE studyid > 10 AND studyid < 100;
SELECT * FROM DX WHERE studyid > 10 AND studyid < 100 ORDER BY studyid;
SELECT * FROM DX2 WHERE studyid > 10 AND studyid < 100 ORDER BY studyid;

SELECT * FROM DX2 WHERE studyid > 10 AND studyid < 100 ORDER BY studyid;
SELECT * FROM DX WHERE studyid > 10 AND studyid < 100;
SELECT * FROM DX WHERE studyid > 10 AND studyid < 100 ORDER BY studyid;

и посмотрите на результаты (затраченное время) за последние 6запросов они: -

SELECT * FROM DX WHERE studyid > 10 AND studyid < 100
> OK
> Time: 0.007s


SELECT * FROM DX WHERE studyid > 10 AND studyid < 100 ORDER BY studyid
> OK
> Time: 0.008s


SELECT * FROM DX2 WHERE studyid > 10 AND studyid < 100 ORDER BY studyid
> OK
> Time: 0.003s


SELECT * FROM DX2 WHERE studyid > 10 AND studyid < 100 ORDER BY studyid
> OK
> Time: 0.003s


SELECT * FROM DX WHERE studyid > 10 AND studyid < 100
> OK
> Time: 0.007s


SELECT * FROM DX WHERE studyid > 10 AND studyid < 100 ORDER BY studyid
> OK
> Time: 0.009s

Без индекса (таблица DX в отличие от DX2) время заметно длиннее, и шПредложение ORDER BY немного длиннее, чем без, для таблицы DX.

Однако следует также учитывать, что INSERTS, DELETES и некоторые UPDATES будут иметь дополнительные затраты на поддержание индекса (ов).

например вот время от ВСТАВКИ: -

WITH RECURSIVE cte AS (SELECT abs(random() % 1000) UNION ALL SELECT abs(random() % 1000) FROM cte LIMIT 100000)
INSERT INTO DX SELECT * FROM cte
> Affected rows: 100000
> Time: 0.228s


INSERT INTO DX2 SELECT * FROM DX
> Affected rows: 100000
> Time: 0.362s
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...