SQLite3在Swift中查询速度慢

时间:2018-05-02 14:25:48

标签: sql swift sqlite

以下SQLite3语句在我的Swift-Code中非常慢(见下文)

知道为什么吗?

目前,从断点-1到断点-2需要大约30秒

// .. breakpoint-1
while ((sqlite3_step(statement) == SQLITE_ROW) {
   // .. breakpoint-2
}

我的SQLite-db大小为450 MB,查询非常复杂。 我不确定这种“while-loop”是否不能以某种方式变得更快?

以下是查询:

var query1: String = ""

query1 =
"""
SELECT DISTINCT st.departure_time as time, t.trip_headsign, r.route_desc, t.trip_id
FROM stops s
INNER JOIN calendar c ON t.service_id = c.service_id
INNER JOIN stop_times st  ON st.stop_id = s.stop_id
INNER JOIN trips t ON t.trip_id = st.trip_id
INNER JOIN routes r ON r.route_id = t.route_id
WHERE c.\(weekDay) = 1
AND st.departure_time > "\(departureTime)"
AND st.stop_id LIKE '\(stop_id)%'
AND s.stop_name <> t.trip_headsign
ORDER BY st.departure_time ASC
LIMIT 80
"""

此外,在输入maddy之后,我确实创建了一个新数据库 - 这次是“索引”(请参阅​​下面的哪些列...)。索引后 - 数据库的大小增加到原始大小的两倍。

但是使用上述查询和新索引的DB,遗憾的是速度仍然相同(> 30秒)。 在拥有“索引”数据库后,如何更改查询? 如何提高查询速度???

这些是索引列:

CREATE INDEX departure_time_IDX ON stop_times(departure_time);
CREATE INDEX stop_times_id_IDX ON stop_times(stop_id);
CREATE INDEX stop_times_trip_id_IDX ON stop_times(trip_id);
CREATE INDEX stop_name_IDX ON stops(stop_name);
CREATE INDEX stop_id_IDX ON stops(stop_id);
CREATE INDEX trip_headsign_IDX ON trips(trip_headsign);
CREATE INDEX trip_id_IDX ON trips(trip_id);
CREATE INDEX trip_route_id_IDX ON trips(route_id);
CREATE INDEX service_id_IDX ON trips(service_id);
CREATE INDEX route_desc_IDX ON routes(route_desc);
CREATE INDEX route_id_IDX ON routes(route_id);
CREATE INDEX cal_service_id_IDX ON calendar(service_id);
CREATE INDEX monday_IDX ON calendar(monday);
CREATE INDEX tuesday_IDX ON calendar(tuesday);
CREATE INDEX wednesday_IDX ON calendar(wednesday);
CREATE INDEX thursday_IDX ON calendar(thursday);
CREATE INDEX friday_IDX ON calendar(friday);
CREATE INDEX saturday_IDX ON calendar(saturday);
CREATE INDEX sunday_IDX ON calendar(sunday);

以下是EXPLAIN QUERY PLAN

enter image description here

如果我删除了tripsroutes的INNER JOIN,我的查询时间会缩短到3秒。当然,我需要这两个因为我期望的结果。但至少它表明这两个额外表的INNER JOIN正在减慢速度。

此外,必须注意stop_times是最重要的表格! (然后来trips - 其他都小了......)

3秒查询如下所示:

var faster_query: String = ""

faster_query =
"""
SELECT DISTINCT st.departure_time as time
FROM stops s
INNER JOIN stop_times st  ON st.stop_id = s.stop_id
WHERE st.departure_time > "19:51:00"
AND st.stop_id LIKE '8505000%'
ORDER BY st.departure_time ASC
LIMIT 80
"""

faster_query的EXPLAIN QUERY PLAN如下所示:

enter image description here

以下是SQLite3查询的完整代码

// Open SQLite database
var db: OpaquePointer? = nil
if let path = self.departure_filePath?.path {
    if sqlite3_open(path, &db) == SQLITE_OK {

        var statement: OpaquePointer? = nil
        // Run SELECT query from db
        if sqlite3_prepare_v2(db, query1, -1, &statement, nil) == SQLITE_OK {

            // Loop through all results from query1
            // .. breakpoint-1
            while ((sqlite3_step(statement) == SQLITE_ROW) {
                // .. breakpoint-2

                let ID = sqlite3_column_text(statement, 0)
                if ID != nil {
                    IDString = String(cString:ID!)
                } else {
                    print("ID not found", terminator: "")
                    return nil
                }
            }
        }
    }
}

0 个答案:

没有答案