0

我正在执行这个查询:

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+ 次。

4

3 回答 3

2

数据库有 3900+ 行,这个查询必须在不到一秒的时间内重复 1800+ 次。

不会。在使用高度优化的算法扫描内存中数据的机器之外不会发生巨大的内存带宽。

在任何这样的情况下,设计该数据模型以使这种查询根本没有必要是至关重要的。3900 多行确实不算多,但是针对该数据的 1800 多条查询实在是太多了。

你最好的选择是追求一种模式,消除对 1800+ 查询/秒的需求,或者,在最坏的情况下,设计应用程序,使 1800+ 查询/秒在进度条或其他东西后面完成。

于 2013-08-31T19:56:06.537 回答
1

除了@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: Fastest way to get all rows (consecutive disk access)

于 2013-08-31T20:09:03.830 回答
0

在此查询中,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 次查询。

于 2013-08-31T20:08:44.027 回答