【问题标题】:Optimizing SQLite Inner Join Query - Android优化 SQLite 内连接查询 - Android
【发布时间】:2016-01-07 09:35:55
【问题描述】:

我正在与 GTFS 合作,并试图找出一种方法来加快我的内部连接。表格“Trips”和“StopTimes”有一个公共列“TripID”,表格“StopTimes”和“Stops”有一个公共列“StopID”。内连接检索与某个行程对应的所有停靠点,但是它需要大约 20 秒。此外,“StopTimes”表包含 900 万行,而其他表包含几千行。以下代码是我的查询。

String joinQuery = "SELECT s.stop_id, s.stop_code, s.stop_name "
+ "FROM Trips as t INNER JOIN StopTimes as st ON     st.trip_id = t.trip_id "
+ "INNER JOIN Stops as s ON s.stop_id = st.stop_id "
+ "WHERE t.trip_id = " + TripID + " AND t.shape_id = " + ShapeID
+ " ORDER BY st.stop_sequence";

这是创建数据库时执行的代码。

String CREATE_TRIPS_TABLE = "CREATE VIRTUAL TABLE " + TABLE_TRIPS + " USING FTS3("
            + KEY_T_ROUTE_ID + " INTEGER,"
            + KEY_T_NAME + " TEXT,"
            + KEY_TRIP_ID + " INTEGER,"
            + KEY_DIRECTION_ID + " INTEGER,"
            + KEY_SHAPE_ID + " INTEGER);";

    String CREATE_STOPS_TABLE = "CREATE VIRTUAL TABLE " + TABLE_STOPS + " USING FTS3("
            + KEY_STOP_ID + " INTEGER,"
            + KEY_STOP_CODE + " TEXT,"
            + KEY_STOP_NAME + " TEXT,"
            + KEY_STOP_LAT + " DOUBLE,"
            + KEY_STOP_LON + " DOUBLE,"
            + KEY_STOP_WHEELCHAIR + " INTEGER);";

    String CREATE_STOPTIMES_TABLE = "CREATE VIRTUAL TABLE " + TABLE_STOP_TIMES + " USING FTS3("
            + KEY_S_TRIP_ID + " INTEGER,"
            + KEY_S_STOP_ID + " INTEGER,"
            + KEY_ARRIVAL_TIME + " TEXT,"
            + KEY_STOP_SEQUENCE + " INTEGER,"
            + KEY_SHAPE_DIST_TRAVELLED + " DOUBLE);";

我遵循了我在这里找到的一些建议,但仍然无法加快我的查询速度,感谢任何反馈。

更新 我更改了创建表的方式,并为 INNER JOIN 查询中涉及的两个索引添加了索引,现在 JOINS 是即时的。

String CREATE_TRIPS_TABLE = "CREATE TABLE " + TABLE_TRIPS + "("
            + KEY_T_ID + " integer PRIMARY KEY AUTOINCREMENT,"
            + KEY_T_ROUTE_ID + " INTEGER,"
            + KEY_T_NAME + " TEXT,"
            + KEY_TRIP_ID + " INTEGER,"
            + KEY_DIRECTION_ID + " INTEGER,"
            + KEY_SHAPE_ID + " INTEGER);";

    String CREATE_STOPS_TABLE = "CREATE TABLE " + TABLE_STOPS + "("
            + KEY_S_ID + " integer PRIMARY KEY AUTOINCREMENT,"
            + KEY_STOP_ID + " INTEGER,"
            + KEY_STOP_CODE + " TEXT,"
            + KEY_STOP_NAME + " TEXT,"
            + KEY_STOP_LAT + " DOUBLE,"
            + KEY_STOP_LON + " DOUBLE,"
            + KEY_STOP_WHEELCHAIR + " INTEGER);";

    String CREATE_STOPTIMES_TABLE = "CREATE TABLE " + TABLE_STOP_TIMES + "("
            + KEY_ST_ID + " integer PRIMARY KEY AUTOINCREMENT,"
            + KEY_S_TRIP_ID + " INTEGER,"
            + KEY_S_STOP_ID + " INTEGER,"
            + KEY_ARRIVAL_TIME + " TEXT,"
            + KEY_STOP_SEQUENCE + " INTEGER,"
            + KEY_SHAPE_DIST_TRAVELLED + " DOUBLE);";

    db.execSQL(CREATE_ROUTES_TABLE);
    db.execSQL(CREATE_TRIPS_TABLE);
    db.execSQL(CREATE_STOPS_TABLE);
    db.execSQL(CREATE_STOPTIMES_TABLE);
    db.execSQL("CREATE INDEX T_id ON Trips(trip_id)");
    db.execSQL("CREATE INDEX S_t_id ON StopTimes(trip_id)");

【问题讨论】:

  • 您为什么使用the FTS3 extension 而不是构建普通的关系数据库?您是否打算对 GTFS 数据进行全文搜索?
  • @SimonSouth 是的,它应该可以更快地搜索数据
  • 我确信它会使 全文 搜索更快,但我认为它对您在此处显示的查询类型(以及通常运行的查询类型)不利针对 GTFS 数据)。我认为您应该首先尝试以传统方式定义数据库,在适当的列上使用索引,并在尝试使用扩展之前查看查询的执行情况。
  • 感谢您的意见,非常感谢!我会测试一下并发布我的结果
  • 强调我的观点:SQLite does not allow indices on virtual tables,这可能是您的查询需要这么长时间才能完成的原因。

标签: android database sqlite join gtfs


【解决方案1】:

我看到您正在使用SQLite's FTS3 extension,它旨在提高全文搜索的性能。我怀疑这实际上不利于您发出的那种查询(以及通常针对 GTFS 数据运行的那种查询)。

我建议您首先创建一个传统的关系数据库,在适当的列上使用索引,然后测试查询的性能。在这种类型的应用程序中使用时,SQLite 无疑具有良好的性能,所以我想你会感到惊喜。一旦您证明使用传统技术取得了成功,您就可以在必要时寻找其他方法使查询运行得更快。

最后,请注意SQLite does not allow indices on virtual tables,我怀疑这是您的查询现在需要这么长时间才能完成的具体原因。

【讨论】:

  • 非常感谢您提供的所有信息,创建传统数据库确实加快了进程。现在,停靠次数最多的行程不到 10 秒
  • 太棒了!如果您还没有在表上定义索引,那么创建这些索引也会产生巨大的影响。
  • 我很困惑,定义索引?我以为我已经在查询中这样做了
  • 否;使用CREATE INDEX 语句在表本身上创建索引。解释如何以及为什么使用索引对于 Stack Overflow 的回答来说有点过于复杂,因此您可能需要参考有关关系数据库的书籍或教程。不过,根据经验,您通常希望在 JOINWHERE 子句中使用的每一列上创建一个索引。
  • 感谢您的提醒,我一定会调查的。感谢您提供的所有信息!
猜你喜欢
  • 2010-11-06
  • 1970-01-01
  • 1970-01-01
  • 2012-03-16
  • 2011-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多