Al hacer un pedido, SQLite escaneará toda la tabla y cargará todos los valores en un b-tree temporal para ordenarlos, haciendo que cualquier índice sea inútil. Esto será muy lento y utilizar una gran cantidad de memoria en grandes tablas:
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
Puede obtener el siguiente valor inferior o superior utilizando el índice de la siguiente manera:
select min(value) from 'table' where x >= N;
select max(value) from 'table' where x <= N;
Y puede utilizar union
a obtener ambos desde una sola consulta:
explain query plan
select min(value) from 'table' where value >= 10
union select max(value) from 'table' where value <= 10;
1|0|0|SEARCH TABLE table USING COVERING INDEX value_index (value>?)
2|0|0|SEARCH TABLE table USING COVERING INDEX value_index (value<?)
0|0|0|COMPOUND SUBQUERIES 1 AND 2 USING TEMP B-TREE (UNION)
Esto será bastante rápido incluso en las tablas grandes. Usted simplemente puede cargar ambos valores y evaluarlos en su código, o utilizar aún más SQL para seleccionar una de varias maneras:
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
o
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
Puesto que usted está interesado en los valores tanto de forma arbitraria mayores y menos que el objetivo, no puede evitar hacer dos búsquedas de índice. Si usted sabe que el objetivo está dentro de un rango pequeño, sin embargo, se puede usar "entre" sólo para golpear índice una vez:
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
Este será de alrededor de 2 veces más rápido que la consulta de unión por encima de cuando se evalúa únicamente 1 -2 valores, pero si comienza a tener que cargar más datos, se volverá más lento.
Tenga en cuenta que el sistema de tipo sqlite es especial y si tiene un doble verdadero no tiene nada que ver con ninguna declaración de tipo. – unmounted