我有一个正在为 iOS 开发的应用程序,它根据当前视图的边界框在地图上显示轨迹。因此,当用户在地图上移动时,它将加载适当的轨迹集。
SQLite 表很大,有 260k 行,其中每一行都是轨迹上的一个点。该表具有主键 (int)、纬度 (float)、经度 (float) 和名称 (varchar)。纬度和经度列已编入索引。当我查询时,我正在寻找纬度在右下角和左上角纬度之间的位置以及经度在左上角和右下角经度之间的位置。该查询在桌面和手机上都能完美运行,因为它返回了预期的结果。问题是,在我的 Mac 上,查询会立即返回,而在手机上,它可能只需要 4 秒就可以返回任何内容。瓶颈似乎确实是数据库查询,我开始认为这是硬件的限制。
我曾尝试使用 CoreData,这是我首先注意到问题的地方。然后我开始使用 FMDB 访问数据库,但仍然遇到问题。
我没有对数据库或连接进行任何调整。
queryForTrails 方法的核心
if( ![db open] ) {
[db release];
NSLog(@"Error opening DB: %@", dbPath);
}
FMResultSet *trails = [db executeQueryWithFormat:@"SELECT zname, zlatitude, zlongitude FROM ztrail WHERE ztype = 1 and zlatitude BETWEEN %@ and %@ AND zlongitude BETWEEN %@ and %@ order by zname", lrLat, ulLat, ulLon,lrLon];
//Start to load the map with data
NSString *lastTrailName=@"";
int idx = 0;
CLLocationCoordinate2D *trailCoords = nil;
NSUInteger coordSize = 20;
trailCoords = malloc(sizeof(CLLocationCoordinate2D)*coordSize);
while( [trails next] ) {
NSString *trailName = [trails stringForColumnIndex:0];
NSString *lat = [trails stringForColumnIndex:1];
NSString *lon = [trails stringForColumnIndex:2];
if( [lastTrailName compare:trailName] != NSOrderedSame ) {
if(idx > 0) {
[trailLines addObject:[MKPolyline polylineWithCoordinates:trailCoords count:idx]];
free(trailCoords);
idx = 0;
coordSize = 20;
}
lastTrailName = trailName;
trailCoords = malloc(sizeof(CLLocationCoordinate2D)*coordSize);
}
if(idx == coordSize) {
coordSize *= 2;
trailCoords = realloc(trailCoords, sizeof(CLLocationCoordinate2D) * coordSize);
}
trailCoords[idx++] = CLLocationCoordinate2DMake([lat doubleValue], [lon doubleValue]);
}
//Build the new polyline
[trailLines addObject:[MKPolyline polylineWithCoordinates:trailCoords count:idx]];
//NSLog(@"Num Trails: %d", [trailLines count]);
free(trailCoords);
//NSLog(@"Num of Points %d for %@",idx, lastTrailName);
if( [trailLines count] > 0 ) {
dispatch_async(dispatch_get_main_queue(),^{
[mapView addOverlays:trailLines];
});
}
如果需要,我可以提供一些 NSLog 数据。我也会为 Android 做同样的应用程序,所以我现在想尝试解决性能问题。