[英]Does SQLite3 supports indexing? How can I speed up a query?
我正在执行此查询:
NSString *querySQL = [NSString stringWithFormat:@"
SELECT DISTINCT P1.ID_RUTA_PARADAS
FROM FastParadas AS P1
WHERE P1.ID_ESTACION_INIT <= %d AND
%d <= P1.ID_ESTACION_END
INTERSECT
SELECT DISTINCT P2.ID_RUTA_PARADAS
FROM FastParadas AS P2
WHERE P2.ID_ESTACION_INIT <= %d AND
%d <= P2.ID_ESTACION_END",
(int)estacionOrigen.ID_Estacion,(int)estacionOrigen.ID_Estacion,
(int)estacionDestino.ID_Estacion,(int)estacionDestino.ID_Estacion];
我想加快速度。 我尝试创建一些索引,但是没有任何改善。 SQLite3是否支持索引?
该数据库具有3900+行,并且此查询必须在不到一秒钟的时间内重复1800+次。
该数据库具有3900+行,并且此查询必须在不到一秒钟的时间内重复1800+次。
不会。使用高度优化的算法扫描内存中的数据,不会在拥有巨大存储带宽的机器之外发生这种情况。
在这种情况下,至关重要的是,设计数据模型以使这种查询根本不是必需的。 3900多个行实际上并没有那么多,但是针对该数据进行的1800多个查询实在是一个地狱。
最好的选择是采用一种模式,该模式不需要每秒进行1800+次查询,或者在最坏的情况下,设计应用程序以使1800+次/秒在进度条之类的东西下完成。
除了@bbum和@ipmcc关于物理限制的要点外,从理论上讲,您也不会很幸运。 什么是你正在寻找的ID_RUTA_PARADAS
满足所有元组进入ID_ESTACION_INIT
比一些值和ID_ESTACION_END
比一些更大的值(只是为了将它放入自然语言)。
索引有什么帮助呢?
(1)假设您在ID_ESTACION_INIT
上有一个支持范围查询的索引。 您可以相对快地获得满足ID_ESTACION_INIT <= %d
的行的所有ID。 但是然后,您必须获取所有这些行,以便确定它们是否还满足%d <= P1.ID_ESTACION_END
。
(2)假设有关于索引ID_ESTACION_INIT
和一个上ID_ESTACION_END
两个支撑范围查询。 然后,这两个都可以获得满足谓词的所有行,并且两个索引返回的rowid可用于获取ID_RUTA_PARADA
。
这两种方法的问题在于,如果要使用它们,则必须随机访问磁盘,这仅对较小的结果集有意义(即,如果满足这些谓词的行很少)。 对于更大的基数(我想我听说> = 5%,但这可能只是一个例子),数据库系统将进行表扫描以查找所有元组,这意味着索引无济于事。
这里是一个SQLFiddle,可以处理索引以及其他DBMS: http ://sqlfiddle.com/#!5/d1a86/2
(实际上,聚集索引可以帮助读取较少的不合格元组,但是SQLite不支持它们: sqlite:获取所有行的最快方法(连续磁盘访问) )
在此查询中, INTERSECT
已经负责删除重复项,因此您不需要DISTINCT
。 以下查询可能会更快:
SELECT DISTINCT ID_RUTA_PARADAS
FROM FastParadas
WHERE %d BETWEEN ID_ESTACION_INIT AND ID_ESTACION_END
AND %d BETWEEN ID_ESTACION_INIT AND ID_ESTACION_END
但是,使用常规索引无法轻松优化此类范围查询。 您应该更改数据库以使用一维R-tree索引 ,在这种情况下,可能有1800个查询/秒。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.