0

ユーザーがさまざまな方法でTVガイドを表示できるAndroidアプリを開発しています。ビューの1つは、現在/次のビューです。これは基本的に、セパレーター(チャンネル名を表示)と、各セパレーターの後に現在/次のテレビ番組の詳細が続くリストです。

私が抱えている問題は、67チャネルの自分のラインナップをテストすることで、ビューの生成に20〜30秒かかります(モバイルアプリの場合はひどく遅い)。一部のユーザーは200以上のチャネルを持っていることを知っています。

1つのチャネルのNow/Nextの詳細を取得するために使用するSQLクエリは次のとおりです...

SELECT
    b.oid AS _id,
    b.channel_oid,
    b.title,
    b.start_time,
    b.end_time
FROM epg_event b,
    (
        SELECT
            MIN(a.start_time) AS start_time,
            a.channel_oid,
            a.end_time
        FROM epg_event a
        WHERE a.start_time  > datetime('now')
          AND a.channel_oid = 10029
        GROUP BY a.channel_oid
        UNION
        SELECT
            MIN(a.start_time) AS start_time,
            a.channel_oid,
            a.end_time
        FROM epg_event a
        WHERE a.start_time <= datetime('now')
          AND a.end_time    > datetime('now')
          AND a.channel_oid = 10029
        GROUP BY a.channel_oid
    ) c
WHERE c.start_time  = b.start_time
  AND c.channel_oid = b.channel_oid
ORDER BY b.start_time

これは、最初のレコードの開始時刻が現在の時刻の前(または等しい)で、終了時刻が現在の時刻(現在)の後にあり、2番目のレコードの開始時刻が2つのレコードを取得するクエリでは、かなり複雑に思えます。これは、最初の(次へ)の終了時刻と一致します。

この種のシナリオを照会するためのより効率的な方法があるかどうか疑問に思っています。

epg_eventテーブルは、(スキーマを説明するために)次のように作成されます。

CREATE TABLE [EPG_EVENT] (
    [oid] integer PRIMARY KEY,
    [title] varchar(50),
    [subtitle] varchar(50),
    [description] varchar(50),
    [start_time] datetime,
    [end_time] datetime,
    [channel_oid] int,
    [unique_id] varchar(50),
    [rating] varchar(50),
    [original_air_date] datetime,
    [season] int,
    [episode] int,
    [dvb_service_event_id] int,
    [dvb_table_version] int,
    [genres] varchar(50)
)

表示されたクエリは...を返します。

_id, channel_oid, title, start_time, end_time
10467376, 10029, Ripper Street, 2013-01-20 21:00:00, 2013-01-20 22:00:00
10467377, 10029, BBC News; Regional News and Weather, 2013-01-20 22:00:00, 2013-01-20 22:25:00
4

1 に答える 1

1

私が知る限り、クエリのこの部分は、まだ放送されているか、まだ開始されていないことを示すものを取得することになっています。

    SELECT
        MIN(a.start_time) AS start_time,
        a.channel_oid,
        a.end_time
    FROM epg_event a
    WHERE a.start_time  > datetime('now')
      AND a.channel_oid = 10029
    GROUP BY a.channel_oid
    UNION
    SELECT
        MIN(a.start_time) AS start_time,
        a.channel_oid,
        a.end_time
    FROM epg_event a
    WHERE a.start_time <= datetime('now')
      AND a.end_time    > datetime('now')
      AND a.channel_oid = 10029
    GROUP BY a.channel_oid

ただし、これら2つの条件は、showがまだ終了していない条件、または次の条件と同等です。

    SELECT
        MIN(a.start_time) AS start_time,
        a.channel_oid,
        a.end_time
    FROM epg_event a
    WHERE a.end_time    > datetime('now')
      AND a.channel_oid = 10029
    GROUP BY a.channel_oid

さて、ここであなたは既知のchannel_oidでフィルタリングしますが、それでもGROUP BYそれは-なぜですか?次のように簡略化する必要があります

    SELECT
        MIN(a.start_time) AS start_time,
        a.channel_oid,
        a.end_time
    FROM epg_event a
    WHERE a.end_time > datetime('now')
      AND a.channel_oid = 10029

私の知る限りでは、おそらく。に置き換えdatetime('now')たほうがよいでしょうCURRENT_TIMESTAMP。これにより、最終的なSQLは次のようになります。

SELECT
    b.oid AS _id,
    b.channel_oid,
    b.title,
    b.start_time,
    b.end_time
FROM epg_event b,
    (
        SELECT
            MIN(a.start_time) AS start_time,
            a.channel_oid,
            a.end_time
        FROM epg_event a
        WHERE a.end_time > CURRENT_TIMESTAMP
          AND a.channel_oid = 10029
    ) c
WHERE c.start_time  = b.start_time
  AND c.channel_oid = b.channel_oid
ORDER BY b.start_time

高速に動作させるには、適切なインデックスを作成してください。この回答は、それを最適化する方法のいくつかのアイデアを与えることができますが、一見すると、少なくとも次の複合インデックスがepg_eventテーブルにあるはずです:(channel_oid, start_time)(channel_oid, end_time)

于 2013-01-21T01:41:05.777 に答える