【发布时间】: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