2014-07-01 4 views
0

시간이 많이 걸리는 작업은 데이터베이스를 쿼리하여 일부 경로 및 트레일의 위도 및 경도 값을 얻는 것입니다. 이제 여러 가지 유형의 트레일 및 경로에 대해 수행 할 이러한 데이터베이스 작업이 몇 가지 있습니다. 나는 다음을 사용하고있다 :그랜드 센트럴 디스패치를 ​​사용하여 ios 앱의 작동 속도를 향상시킬 수 없습니다.

dispatch_async(myBackgroundQueue, ^(void) { 

      // do some time consuming things here 
      [self queryForHiking: ulLat ulLong:ulLon lrLat:lrLat lrLong:lrLon]; 

      dispatch_async(dispatch_get_main_queue(), ^{ 

       // do some things here in the main queue 
       // for example: update UI controls, etc. 
       [self drawOnMap]; 
      }); 
     }); 

위의 코드 블록과 마찬가지로 나는 5 개의 블록을 가지고있다. drawOnMap 함수는지도에 형성된 흔적과 경로를 그립니다. 그러나지도에서 다른 쿼리의 모든 경로를 렌더링하는 데 많은 시간이 걸립니다. 특히 렌더링 할 데이터가 많은 더 높은 줌 레벨에서는 앱이 멈추고 데이터를 다시 표시하고 표시하는 데 많은 시간이 걸립니다. 어떻게 효율적으로 만들 수 있습니까?

편집 : 여기서는 쿼리에 많은 시간이 걸리고 서로 독립적 인 이러한 쿼리가 5 개 있다고 생각합니다. 다시 그리기로 촬영 0.053462 시간 : 쿼리에 의해 촬영

시간 : 다음

- (void)queryForHikingTrails:(NSString*)ulLat ulLong:(NSString*)ulLong lrLat:(NSString*)lrLat lrLong:(NSString*)lrLong 
{ 
    @try { 
     [_db inDatabase:^(FMDatabase *db) { 

      FMResultSet *trails = [db executeQueryWithFormat:@"SELECT ID2,Latitude, Longitude FROM hikingtrails WHERE Latitude BETWEEN %@ and %@ AND Longitude BETWEEN %@ and %@", lrLat, ulLat, lrLong, ulLong]; 

      hikingTrails = [self buildTrails:trails]; 
     }]; 
    } 
    @catch (NSException *e) { 
     NSLog(@"Error Querying for Trails: %@ - %@", [e name], [e reason]); 
    } 
    @finally { 
    } 
} 

난 그냥이 쿼리 (하이킹)을 실행할 때 걸리는 시간입니다 : 다음은 내 오 쿼리 기능 중 하나입니다 기능 (drawOnMap) = 0.000008

나는 두 개의 질의 (하이킹 + 다른 산책로) 실행 쿼리에 의해 촬영

시간 : 다시 그리기 기능에 의해 촬영 2.681138 시간 (drawOnMap) = 0.000010

나는 어떤 방법 으로든 데이터베이스를 변경할 수있는 권한이 없습니다. 즉, 테이블을 분할하거나 정규화 할 수 없습니다.

데이터베이스는 위 함수가 조회하려고하는 약 18000 개의 항목으로 구성됩니다.

데이터베이스 최적화를 적용하여 쿼리를 빠르게 만들고, 적어도 동시에 백그라운드에서 실행하십시오 (모두 5)?

EDIT : 추가 조사를 해본 결과 다른 쿼리가 시간이 많이 걸리지 않는 반면 많은 쿼리를 수행하는 쿼리가 11.7834에 불과하다는 것을 발견했습니다. 이 특정 쿼리는 어떻게 처리해야합니까? 지도 뷰를 차단하지 않고이 쿼리를 백그라운드에서 실행할 수있는 방법이 있습니까? 이 쿼리가 실행될 때마다 mapview가 drawOnMap 함수에 의해 새로 고침되기 때문에 어떻게 가능할 지 모르겠습니다. 나를 안내 해줘.

+0

은 시간이 쿼리 나 도면에 의한인지 여부를 확인 :

NSOperation 종속성을 동시에 수행하고, 그 작업이 완료되면 마지막으로 업데이 트를 할 수 있습니다 당신에게 그 일을 지정하는 쉬운 방법을 제공 그런 다음 최적화하려는 특정 코드에 대한 자세한 내용으로 질문을 업데이트하십시오. – erikprice

+0

@ erikprice- 질문을 업데이트했습니다. –

+1

그건 일종의 @erikprice, 당신은 생각하지 않습니다 * 뭔가 * 많은 시간이 걸립니다. 당신은 그것을 측정합니다. 타이밍 코드를 삽입하고 (''NSDate''와의 비교는 괜찮을 것입니다.) 우선 병목 현상을 파악하십시오. DB로드가 UI 드로잉에 비해 얼마나 오래 걸리는지 측정 한 다음 가장 느린 것을 최적화합니다. 그런 다음 만족할 때까지 반복하십시오. SQL의 경우 인덱스 또는 테이블 분할이 있습니다. –

답변

1

내가 아래에서 제안하는 접근 방식이 도움이 될지 모르지만 도움이 될 수 있습니다. 쿼리를 동시에 실행하기 위해 작업 대기열을 사용하며 모두 완료되면 -[self drawOnMap]을 호출합니다. 그러나 올바르게 작동하려면 각 쿼리가 현재 스레드를 차단해야합니다. 원래 GCD 기반 코드에서 추측했습니다. 또한 쿼리 메소드가 동시에 안전하게 실행할 수 있다고 가정합니다 (예 : 쿼리 결과로 수행하는 작업을 여러 스레드에서 안전하게 수행 할 수 있음).

self.queryQueue = [[NSOperationQueue alloc] init]; 

NSBlockOperation *queriesOperation = [NSBlockOperation blockOperationWithBlock:^{ 
    [self queryForHiking:ulLat ulLong:ulLon lrLat:lrLat lrLong:lrLon]; 
}]; 
[queriesOperation addOperation:^{ 
    [self performSomeOtherQuery]; 
}]; 
[queriesOperation addOperation:^{ 
    [self performYetAnotherQuery]; 
}]; 
// do this for each of your queries 

NSOperation *drawOperation = [NSBlockOperation blockOperationWithBlock:^{ 
    [self drawOnMap]; 
}]; 
[drawOperation addDependency:queriesOperation]; 

[self.queryQueue addOperation:queriesOperation]; 
[NSOperationQueue.mainQueue addOperation:drawOperation]; 
+0

비록이 문제는 비효율적 인 SQL 조인 쿼리로 밝혀졌습니다. 그래도 데이터 렌더링이 향상되었는지 확인하기 위해 귀하의 아이디어를 사용했습니다. 그것은 도왔다! 그래서 나는 당신의 대답을 받아들입니다. 감사. –