Mithilfe einer order-by wird SQLite die gesamte Tabelle scannen und alle Werte in eine temporäre b-Struktur laden, um sie zu ordnen, wodurch jeder Index unbrauchbar wird. Dies wird sehr langsam sein und viel Speicher für große Tabellen verwenden:
explain query plan select * from 'table' order by abs(10 - value) limit 1;
0|0|0|SCAN TABLE table
0|0|0|USE TEMP B-TREE FOR ORDER BY
Sie können die nächst niedrigeren oder höheren Wert zu bekommen, den Index wie folgt aus:
select min(value) from 'table' where x >= N;
select max(value) from 'table' where x <= N;
Und können Sie union
verwenden bekomme beide von einer einzigen Abfrage:
Dies wird auch auf großen Tabellen ziemlich schnell sein. Sie könnten einfach beide Werte laden und sie in Ihrem Code bewerten, oder verwenden sogar mehr SQL ein auf verschiedene Weise zu wählen:
explain query plan select v from
( select min(value) as v from 'table' where value >= 10
union select max(value) as v from 'table' where value <= 10)
order by abs(10-v) limit 1;
2|0|0|SEARCH TABLE table USING COVERING INDEX value_index (value>?)
3|0|0|SEARCH TABLE table USING COVERING INDEX value_index (value<?)
1|0|0|COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (UNION)
0|0|0|SCAN SUBQUERY 1
0|0|0|USE TEMP B-TREE FOR ORDER BY
oder
explain query plan select 10+v from
( select min(value)-10 as v from 'table' where value >= 10
union select max(value)-10 as v from 'table' where value <= 10)
group by v having max(abs(v)) limit 1;
2|0|0|SEARCH TABLE table USING COVERING INDEX value_index (value>?)
3|0|0|SEARCH TABLE table USING COVERING INDEX value_index (value<?)
1|0|0|COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (UNION)
0|0|0|SCAN SUBQUERY 1
0|0|0|USE TEMP B-TREE FOR GROUP BY
Da Sie in Werte interessiert sind beide willkürlich größer und weniger als das Ziel, können Sie nicht zwei Indexsuchen vermeiden. Wenn Sie wissen, dass das Ziel in einem kleinen Bereich ist aber, könnte man „zwischen“ verwenden, nur den Index einmal getroffen:
explain query plan select * from 'table' where value between 9 and 11 order by abs(10-value) limit 1;
0|0|0|SEARCH TABLE table USING COVERING INDEX value_index (value>? AND value<?)
0|0|0|USE TEMP B-TREE FOR ORDER BY
Dies wird rund 2x schneller als die Union-Abfrage oben, wenn es wertet nur 1 -2 Werte, aber wenn Sie beginnen, mehr Daten zu laden, wird es schnell langsamer.
Beachten Sie, dass das SQLite-System speziell ist und ob Sie ein echtes Double haben, hat nichts mit Typdeklarationen zu tun. – unmounted