Следующий оператор SQLite3 очень медленный в моем Swift-коде (см. Ниже)
Есть идеи почему ??
В настоящее время от точки останова-1 до точки останова-2 требуется около 30 секунд
// .. breakpoint-1
while ((sqlite3_step(statement) == SQLITE_ROW) {
// .. breakpoint-2
}
Мой SQLite-db имеет размер 450 МБ, и запрос довольно сложный.
Я просто не уверен, что этот "цикл" не может быть как-то ускорен ??
Вот запрос:
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 я создал новую БД - на этот раз «проиндексированную» (см. Столбцы ниже ..). После индексации - размер БД увеличился вдвое по сравнению с первоначальным размером.
Но с учетом вышеприведенного запроса и недавно проиндексированной БД скорость, к сожалению, все еще одинаково низкая (> 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
У меня будет запрос до 3 секунд, если я уберу ВНУТРЕННЕЕ СОЕДИНЕНИЕ trips
и routes
. Конечно, мне нужны эти два для результата, которого я ожидаю от этого. Но, по крайней мере, это показывает, что ВНУТРЕННИЕ СОЕДИНЕНИЯ этих двух дополнительных таблиц замедляют работу.
Также следует заметить, что 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
выглядит так:
Вот весь код запроса 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
}
}
}
}
}