如何用日期和优化来优化sqlite查询SUBSTR?

时间:2009-07-05 17:36:49

标签: objective-c iphone performance sqlite

我有一些sqlite查询正在减慢我的iPhone应用程序。

我有2个模式,我在我的应用程序中重复。第一个是substr:

SELECT Id FROM [Table] WHERE UPPER(substr(Name,1,1))='A' ORDER BY Name"

(这是针对字母表的多样性运行的。是针对联系人列表的)

另一个是复杂的日期:

SELECT Id,customerCode, 
case
when DueDate>=datetime('now','-100 years') AND DueDate<=datetime('now','-1 days') then 'Past due'
when DueDate<datetime('now') then 'Today'
when DueDate>=datetime('now') AND DueDate<=datetime('now','15 days') then '15'
when DueDate>=datetime('now','16 days') AND DueDate<=datetime('now','30 days') then '30'
when DueDate>=datetime('now','31 days') AND DueDate<=datetime('now','45 days') then '45'
when DueDate>=datetime('now','46 days') AND DueDate<=datetime('now','60 days') then '60'
when DueDate>=datetime('now','61 days') AND DueDate<=datetime('now','90 days') then '90'
when DueDate>=datetime('now','91 days') then '> 90'
end As Key, 
COUNT(*) As Total, TimeStamp
FROM debt
GROUP BY customerCode,
case
when DueDate>=datetime('now','-100 years') AND DueDate<=datetime('now','-1 days') then '-1'
when DueDate<datetime('now') then 'Today'
when DueDate>=datetime('now') AND DueDate<=datetime('now','15 days') then '15'
when DueDate>=datetime('now','16 days') AND DueDate<=datetime('now','30 days') then '30'
when DueDate>=datetime('now','31 days') AND DueDate<=datetime('now','45 days') then '45'
when DueDate>=datetime('now','46 days') AND DueDate<=datetime('now','60 days') then '60'
when DueDate>=datetime('now','61 days') AND DueDate<=datetime('now','90 days') then '90'
when DueDate>=datetime('now','91 days') then '> 90'
end

在这两种情况下,我都有日期和时间的索引。 varchar字段。

第一次在模拟器中运行正常,在iPod touch 2 GEN

中需要11秒

iPhone模拟器中的第二个查询也很慢(3秒)&amp;在设备中1分钟。日期使用ISO日期表格。

我很想为数据构建一个缓存表(并为更新提供trigers。数据是实时的,用户可以修改它),但是想知道是否存在更好的方法。

2 个答案:

答案 0 :(得分:3)

我不知道性能如何比较,但另一种编写第一个查询的方法是

SELECT Id FROM [Table] WHERE Name LIKE "a%"

因为%匹配任何以a或A开头的字符串,后跟任意数量的字符。

有关详情,请参阅http://www.sqlite.org/lang_expr.html#like

其次,我猜你在重复调用datetime时会受到性能影响。您可以将其压缩成单个数学运算,然后使用简单的数学运算符比较天数的差异吗?例如,自去年圣诞节以来的天数:

sqlite> select julianday('now') - julianday('2008-12-05');
212.743649386801

SQLite在内部将日期存储为字符串,因此每次调用datetime时,都必须完全解析日期字符串等。

答案 1 :(得分:0)

您不必重复CASE运算符两次 - 只需GROUP BY CustomerCode, Key即可。另外,正如@Mark建议的那样,可以通过使用julianday中的差异来优化CASE,并通过利用LIKE默认情况下不区分大小写的事实来选择名称(只要你只需要ASCII字母 - 唉,这是sqlite中记录的错误,这种情况不敏感在ASCII之外无法正常工作。)