我有一些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。数据是实时的,用户可以修改它),但是想知道是否存在更好的方法。
答案 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之外无法正常工作。)