繁体   English   中英

SQLite3是否支持索引? 如何加快查询速度?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM