我开发了一款Android应用,允许用户以各种方式观看电视指南。其中一个视图是一个Now / Next视图,它基本上是一个带有分隔符(显示频道名称)的列表,每个分隔符后跟当前/下一个电视节目详细信息。
我遇到的问题是测试我自己的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条记录的查询看起来相当复杂,其中第一条记录的开始时间在当前时间之前(或等于)当前时间之前,结束时间在当前时间之后(现在),第二条记录有与第一个(下一个)的结束时间匹配的开始时间。
我只是想知道是否有更有效的方法来查询这种情况。
使用以下内容创建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
答案 0 :(得分: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
但是,这两个条件相当于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
要使其快速运行,请确保创建正确的索引。 This answer可以为您提供一些如何优化它的建议,但首先,您应该在epg_event
表上至少包含以下复合索引:(channel_oid, start_time)
和(channel_oid, end_time)
。