使此SQLite查询更高效
我开发了一个Android应用程序,允许用户以各种方式查看电视指南。其中一个视图是“现在/下一个”视图,它基本上是一个带有分隔符(显示频道名称)的列表,每个分隔符后跟当前/下一个电视节目的详细信息 我遇到的问题是,测试我自己的67个频道阵容需要20-30秒才能生成视图(移动应用程序的速度非常慢),我知道我的一些用户拥有约200多个频道 我用于获取1个通道的“现在/下一个”详细信息的SQL查询如下所示使此SQLite查询更高效,sqlite,android-sqlite,Sqlite,Android Sqlite,我开发了一个Android应用程序,允许用户以各种方式查看电视指南。其中一个视图是“现在/下一个”视图,它基本上是一个带有分隔符(显示频道名称)的列表,每个分隔符后跟当前/下一个电视节目的详细信息 我遇到的问题是,测试我自己的67个频道阵容需要20-30秒才能生成视图(移动应用程序的速度非常慢),我知道我的一些用户拥有约200多个频道 我用于获取1个通道的“现在/下一个”详细信息的SQL查询如下所示 SELECT b.oid AS _id, b.channel_oid,
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
显示的查询将返回
_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
据我所知,您的查询的这一部分应该得到任何仍在播放或尚未开始的节目:
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
现在,您可以按已知的频道ID进行过滤,但仍按它进行分组-为什么?它应该简化为
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\u 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\u event
表上有以下复合索引:(channel\u oid,start\u time)
和(channel\u oid,end\u time)
在Jelly Bean之前的Android版本中必须这样做吗?(你的查询没有。)@CL:我已经编辑了这个问题,以显示用于该表的创建表
。至于它在Jelly Bean之前的版本上的工作,我可以向你保证,我的HTC Desire运行Froyo可以很好地运行查询(尽管速度很慢)。谢谢。我的原始查询实际上得到了一些帮助,因为SQL不是我的强项——我不知道为什么帮助我的人使用GROUP BY。我已经将我的查询压缩为您建议的查询,尽管它只返回1条记录(现在显示的一条),所以我将联合添加到了中,并且它可以工作。然而,真正的解决方法是复合索引——没有它们,压缩查询的速度不会明显加快,但当我添加它们时,它确实起了作用(1-2秒,而不是20-30秒)。再次感谢。很高兴听到这对你有帮助!复合索引确实可以让您的一天变得更美好:-)
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
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