簡體   English   中英

優化SQLite內部聯接查詢-Android

[英]Optimizing SQLite Inner Join Query - Android

我正在與GTFS一起工作,試圖找出一種加快內部聯接速度的方法。 表“ Trips”和“ StopTimes”具有公共列“ TripID”,表“ StopTimes”和“ Stops”具有公共列“ StopID”。 內部聯接檢索與某個Trip對應的所有Stop,但是大約需要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);";

我遵循了在這里找到的一些建議,但仍然無法加快查詢速度,感謝您提供任何反饋。

UPDATE我更改了表的創建方式,並為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)");

我看到您正在使用SQLite的FTS3擴展名 ,該擴展名旨在提高全文搜索的性能。 我懷疑這實際上對您正在發出的查詢(以及通常針對GTFS數據運行的查詢)不利於您。

我建議您首先創建一個常規的關系數據庫,並在相應的列上創建索引,然后針對該數據庫測試查詢的性能。 當在這種類型的應用程序中使用SQLite時,它肯定具有良好的性能,因此,我認為您會感到驚喜。 一旦證明了傳統技術的成功,您就可以根據需要尋找其他方法來使查詢運行更快。

最后,請注意SQLite不允許在虛擬表上創建索引 ,我懷疑這是您的查詢現在花很長時間才能完成的特定原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM