0

我开发了一个 Android 应用程序,它允许用户以各种方式查看电视指南。其中一个视图是现在/下一个视图,它基本上是一个带有分隔符的列表(显示频道名称),每个分隔符后跟当前/下一个电视节目的详细信息。

我遇到的问题是测试我自己的 67 个频道阵容,生成视图需要 20-30 秒(移动应用程序非常慢),我知道我的一些用户有大约 200 多个频道。

我用来获取 1 个通道的现在/下一个详细信息的 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 条记录的查询来说,这似乎非常复杂,其中第 1 条的开始时间在(或等于)当前时间之前(或等于)当前时间,结束时间在当前时间(现在)之后,并且第二条记录有开始时间这与第一个(下一个)的结束时间相匹配。

我只是想知道是否有更有效的方法来查询这种情况。

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

但是,这两个条件等价于表演还没有结束的条件,或者:

    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_eventtable:(channel_oid, start_time)(channel_oid, end_time).

于 2013-01-21T01:41:05.777 回答