iPhone SQLite(FMDB)查询耗时过长
iPhone SQLite(FMDB)查询耗时过长,iphone,sqlite,query-optimization,fmdb,Iphone,Sqlite,Query Optimization,Fmdb,我正在尝试执行一个查询,其中包含group by子句 查询在0.012243秒内执行 但是,当我执行[resultset next]时,第一次调用它需要5秒钟以上的时间 范例 NSMutableArray *recordsArray = [[NSMutableArray alloc] init]; NSString * query = @"select count(id), SUBSTR(purchase_date, 0,11) as purchase_date from sales wher
我正在尝试执行一个查询,其中包含group by子句
查询在0.012243秒内执行
但是,当我执行[resultset next]时,第一次调用它需要5秒钟以上的时间 范例
NSMutableArray *recordsArray = [[NSMutableArray alloc] init];
NSString * query = @"select count(id), SUBSTR(purchase_date, 0,11) as purchase_date from sales where purchase_date LIKE '2012-12%' group by purchase_date order by purchase_date asc";
NSDate * date1 = [NSDate date];
FMResultSet * resultset = [database executeQuery:query];
NSDate * date2 = [NSDate date];
NSTimeInterval timeTaken = [date2 timeIntervalSinceDate:date1];
NSLog(@"TimeTaken: %f", timeTaken); //outputs around 0.012
while ([resultset next])
{
[recordsArray addObject:[resultset resultDictionary]];
}
date2 = [NSDate date];
timeTaken = [date2 timeIntervalSinceDate:date1];
NSLog(@"TimeTaken 2: %f", timeTaken); //outputs around 5.5 seconds
我还能够确定所花费的所有时间都是在第一次调用[resultset next]期间
我还尝试通过生成一个联合查询来修改查询,以删除group by子句,如
NSString * query2 = @"select * from
(
select count(id), SUBSTR(purchase_date, 0,11) as purchase_date from sales where purchase_date = 2012-12-01
UNION
select count(id), SUBSTR(purchase_date, 0,11) as purchase_date from sales where purchase_date = 2012-12-02
UNION
select count(id), SUBSTR(purchase_date, 0,11) as purchase_date from sales where purchase_date = 2012-12-03
....
UNION
select count(id), SUBSTR(purchase_date, 0,11) as purchase_date from sales where purchase_date = 2012-12-31
) where purcase_date is not NULL order by purchase_date asc";
执行此查询也需要0.2秒,但第一次调用[resultset next]时,时间会超过7秒
其他信息该表目前有8000多行,但对于我的一些用户来说,这个数字可能高达100K 我正在使用这些数据绘制给定月份的销售趋势图 在模拟器上,此查询在不到0.5秒的时间内执行,但在设备上需要花费大量时间 问题
你能告诉我如何缩短这个查询的时间吗?我确定最大的瓶颈是SUBSTR和groupby子句,执行和处理一个简单的查询只需要大约0.02秒
Select purchase_date from sales where purchase_date LIKE '2012-12%' order by purchase_date asc;
所以我把它作为一个内部查询引入
Select count(purcahse_date) as count, SUBSTR(purchase_date, 0, 11) as purchase_date from
(
Select purchase_date from sales where purchase_date LIKE '2012-12%'
)
group by purchase_date, order by purchase_date;
虽然生成的数据与最初的查询相同,但天空的时间再次飙升至5.5秒左右
所以最后我决定咬紧牙关,到目前为止,我的最终解决方案是获取给定月份的所有购买日期记录,并自行处理
现在代码是这样的
while ([resultset next])
{
[recordsArray addObject:[resultset resultDictionary]];
}
[resultset close];
[self closeDB];
//release the db lock at this point
int array[31]; //maximum days in a month
bzero((void *)array, 31 * sizeof(int)); //initialize the month array
for(NSDictionary * d in recordsArray) //read the records received from the db and add daily sales count
{
NSRange r;
r.location = 8;
r.length = 2;
int dDate = [[[d objectForKey:@"purchase_date"] substringWithRange:r] intValue];
array[dDate-1]++;
}
[recordsArray removeAllObjects];
//refDate contains @"2012-12"
for(int i=0; i<31; i++) //now populate the final array again
{
if(array[i] > 0)
{
NSDictionary * d1 = [NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"%@-%02d", refDate, i+1], @"date", [NSNumber numberWithInt:array[i]], @"count", nil];
[recordsArray addObject:d1];
}
}
return recordsArray;
while([resultset next])
{
[recordsArray添加对象:[resultset resultDictionary]];
}
[结果集关闭];
[自关闭数据库];
//此时释放db锁
int数组[31]//一个月内的最大天数
bzero((void*)数组,31*sizeof(int))//初始化月份数组
for(recordsArray中的NSDictionary*d)//读取从数据库接收的记录并添加每日销售计数
{
NSRange;
r、 位置=8;
r、 长度=2;
int dDate=[[d objectForKey:@“购买日期”]子字符串范围:r]intValue];
数组[dDate-1]++;
}
[记录射线移除所有对象];
//参考日期包含@“2012-12”
对于(int i=0;i 0)
{
NSDictionary*d1=[NSDictionary Dictionary WithObjectsSandKeys:[NSString stringWithFormat:@“%@-%02d”、refDate,i+1]、@“date”、[NSNumber numberWithInt:array[i]]、@“count”,nil];
[recordsArray添加对象:d1];
}
}
返回记录射线;
我希望它能帮助其他陷入类似情况的人,或者一些db专家可能会建议一些比这个丑陋的解决方案更好的替代方案