Без указания 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](https://i.stack.imgur.com/uCyTA.png)
Второй результат (ORDER BY, но индекс не покрывает studyid) также сканирует таблицу через встроенное B-дерево: -
![enter image description here](https://i.stack.imgur.com/k0Gs6.png)
Третий результат, когда существует индекс в столбце Studyid, использует индекс studyid согласно: -
![enter image description here](https://i.stack.imgur.com/NxQHj.png)
Если вы затем рассмотрите пример с разумным количеством данных (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