0

Android(SQlite)でGTFSデータを扱っています。また、GTFS データで満たされたデータベースでクエリを選択するときのパフォーマンスを改善したいと考えています。

次のクエリは、停車地でのルートに関連付けられた停車時間を選択します。

最初のサブクエリは、木曜日の毎日の停止時刻を取得します。2 番目は、TODAY (2013-07-25) には無効なすべての例外終了時刻を取得します。3 番目のものは、TODAY (2013-07-25) にのみ有効なすべての例外停止時間を取得します。次に、無効なものを削除し、有効なものを最初のサブクエリに追加します。

select distinct stop_times_arrival_time
from stop_times, trips, calendar
where stop_times_trip_id=trip_id
and calendar_service_id=trip_service_id
and trip_route_id='11821949021891616'
and stop_times_stop_id='3377699721872252'
and calendar_start_date<='20130725'
and calendar_end_date>='20130725'
and calendar_thursday=1
and stop_times_arrival_time>='07:40'

except

select stop_times_arrival_time
from stop_times, trips, calendar, calendar_dates
where stop_times_trip_id=trip_id
and calendar_service_id=trip_service_id
and calendar_dates_service_id = trip_service_id
and trip_route_id='11821949021891694'
and stop_times_stop_id='3377699720880977'
and calendar_thursday=1
and calendar_dates_exception_type=2
and stop_times_arrival_time > '07:40'
and calendar_dates_date = 20130725

union

select stop_times_arrival_time
from stop_times, trips, calendar, calendar_dates
where stop_times_trip_id=trip_id
and calendar_service_id=trip_service_id
and calendar_dates_service_id = trip_service_id
and trip_route_id='11821949021891694'
and stop_times_stop_id='3377699720880977'
and calendar_thursday=1
and calendar_dates_exception_type=1
and stop_times_arrival_time > '07:40'
and calendar_dates_date = 20130725;

計算に約 15 秒かかりました (非常に長い)。時間がかかる3つの異なるクエリ(ちなみにほぼ同じ)を実行するため、このクエリを実行する方が良いと確信しています。

それを改善する方法はありますか?

編集:スキーマは次のとおりです。

table|calendar|calendar|2|CREATE TABLE calendar (
    calendar_service_id TEXT PRIMARY KEY,
    calendar_monday INTEGER,
    calendar_tuesday INTEGER,
    calendar_wednesday INTEGER,
    calendar_thursday INTEGER,
    calendar_friday INTEGER,
    calendar_saturday INTEGER,
    calendar_sunday INTEGER,
    calendar_start_date TEXT,
    calendar_end_date TEXT
)
index|sqlite_autoindex_calendar_1|calendar|3|
table|calendar_dates|calendar_dates|4|CREATE TABLE calendar_dates (
        calendar_dates_service_id TEXT,
        calendar_dates_date TEXT,
        calendar_dates_exception_type INTEGER
)
table|routes|routes|8|CREATE TABLE routes (
        route_id TEXT PRIMARY KEY,
        route_short_name TEXT,
        route_long_name TEXT,
        route_type INTEGER,
        route_color TEXT
)
index|sqlite_autoindex_routes_1|routes|9|
table|stop_times|stop_times|12|CREATE TABLE stop_times (
        stop_times_trip_id TEXT,
        stop_times_stop_id TEXT,
        stop_times_stop_sequence INTEGER,
        stop_times_arrival_time TEXT,
        stop_times_pickup_type INTEGER
)
table|stops|stops|13|CREATE TABLE stops (
        stop_id TEXT PRIMARY KEY,
        stop_name TEXT,
        stop_lat REAL,
        stop_lon REAL
)
index|sqlite_autoindex_stops_1|stops|14|
table|trips|trips|15|CREATE TABLE trips (
        trip_id TEXT PRIMARY KEY,
        trip_service_id TEXT,
        trip_route_id TEXT,
        trip_headsign TEXT,
        trip_direction_id INTEGER,
        trip_shape_id TEXT
)
index|sqlite_autoindex_trips_1|trips|16|

そして、ここにクエリプランがあります:

2|0|0|SCAN TABLE stop_times (~33333 rows)
2|1|1|SEARCH TABLE trips USING INDEX sqlite_autoindex_trips_1 (trip_id=?) (~1 rows)
2|2|2|SEARCH TABLE calendar USING INDEX sqlite_autoindex_calendar_1 (calendar_service_id=?) (~1 rows)
3|0|3|SCAN TABLE calendar_dates (~10000 rows)
3|1|2|SEARCH TABLE calendar USING INDEX sqlite_autoindex_calendar_1 (calendar_service_id=?) (~1 rows)
3|2|0|SEARCH TABLE stop_times USING AUTOMATIC COVERING INDEX (stop_times_stop_id=?) (~7 rows)
3|3|1|SEARCH TABLE trips USING INDEX sqlite_autoindex_trips_1 (trip_id=?) (~1 rows)
1|0|0|COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (EXCEPT)
4|0|3|SCAN TABLE calendar_dates (~10000 rows)
4|1|2|SEARCH TABLE calendar USING INDEX sqlite_autoindex_calendar_1 (calendar_service_id=?) (~1 rows)
4|2|0|SEARCH TABLE stop_times USING AUTOMATIC COVERING INDEX (stop_times_stop_id=?) (~7 rows)
4|3|1|SEARCH TABLE trips USING INDEX sqlite_autoindex_trips_1 (trip_id=?) (~1 rows)
0|0|0|COMPOUND SUBQUERIES 1 AND 4 USING TEMP B-TREE (UNION)
4

1 に答える 1

0

ルックアップに使用される列にはインデックスを付ける必要がありますが、単一の (サブ) クエリの場合、テーブルごとに複数のインデックスを使用することはできません。

この特定のクエリでは、次の追加のインデックスが役立ちます。

CREATE INDEX some_index ON stop_times(
    stop_times_stop_id,
    stop_times_arrival_time);
CREATE INDEX some_other_index ON calendar_dates(
    calendar_dates_service_id,
    calendar_dates_exception_type,
    calendar_dates_date);
于 2013-07-28T13:11:42.337 に答える