2010-08-05 4 views
1

나는 약 2500 개의 큰 테이블을 가지고 있습니다. 나는 그것을 tableview에 표시하고있다. 그러나 동적 검색을 수행하는 동안 검색 막대가 너무 느립니다. 즉, 사용자가 검색 창에있는 문자를 넣을 때마다 표를 필터링하고 있습니다.iphone의 tableview에서 sqlite db의 텍스트 검색이 너무 느립니다.

다음은 코드입니다 :

- (void)searchBar:(UISearchBar *)theSearchBar textDidChange:(NSString *)searchText { 
if([searchText length] > 0) { 
    searching = YES; 
    letUserSelectRow = YES; 
    self.tableView.scrollEnabled = YES; 
    [self searchTableView]; 
} else { 
    searching = NO; 
    letUserSelectRow = NO; 
    self.tableView.scrollEnabled = NO; 
    [whereClause setString: @"%%"]; 
} 

[self.tableView reloadData]; 
    } 


- (void) searchTableView { 

NSString *searchText = searchBar.text; 

[whereClause setString: @"%%"]; 
[whereClause appendString: searchText]; 
[whereClause appendString: @"%%"]; 

[self.tableView reloadData]; 
} 

whereClause는 SQLite는 쿼리에있다, 그래서 검색 문자를 추가 유지합니다. 사용자가 키보드 키를 입력 할 때 키가 끈적 거리며 입력하기가 어려워집니다. 모든 제안은 감사하겠습니다 ...

답변

1

첫 번째 문자 뒤에 결과 데이터를 배열로 복사 한 다음 술어를 사용하여 배열을 필터링하십시오. 훨씬 빠릅니다. 그런 다음 배열에서 테이블을 다시로드하십시오. 배열은 사전의 배열 일 수 있습니다. 각 요소는 검색 문자열 (예 : 이름 또는 기타)이 포함 된 사전이고 다른 항목은 최종 선택 항목으로 사용할 핵심 데이터 항목에 대한 참조입니다. 또는 사용자가 선택을 할 때 마지막에 핵심 데이터를 선택할 수 있습니다.

조건자를 사용하여 필터링 할 때 배열의 개체에는 검색하려는 개체와 일치하는 속성이 있어야합니다. 내 예에서는 fullName emailAddressString 속성을 가진 개체를 만들었습니다.

predicate = [NSPredicate predicateWithFormat : @ ""fullName에는 [cd] % @ 또는 emailAddressString에는 [cd] % @ ", searchString, searchString]이 포함됩니다.

NSArray * resultArray = [[NSArray alloc] initWithArray : [allContacts filteredArrayUsingPredicate : predicate]]];

3

SQLite의 선택은 대개 매우 빠릅니다. 몇 가지 샘플 쿼리를 게시 한 경우 도움이 될 수 있습니다.

그러나 : 천천히 수행하는 간단한 WHERE 절을 사용하는 쿼리가있는 경우 검색중인 열의 인덱스가없는 것일 수 있습니다. 하나 추가하십시오.

테이블에있는 2500 항목은 아니요 SQLite에 대해 큽니다. 25,000,000이 클 것입니다.

SQLite로 작업 할 때 sqlite3 셸을 사용하여 데스크탑에서 많은 것을 테스트 할 수 있습니다. 당신이 볼 경우

EXPLAIN QUERY PLAN SELECT * FROM MyTable WHERE Column='A'; 

이 같은 출력 :

0|0|TABLE MyTable 

그것은 SQLite는 크롤링 의미 당신이 뭔가를 할 수

SELECT * FROM MyTable WHERE Column='A'; 

: 예를 들어, 귀하의 요청에 뭔가 같은 경우 전체 테이블 결과를 얻을 수 있습니다. 인덱스를 추가하는이 경우

은 도움이 될 :

CREATE INDEX MyTableColumn ON MyTable(Column); 

을 그리고, 위의 설명 당신에게 대신이 같은 줄 것이다 :

0|0|TABLE MyTable WITH INDEX MyTableColumn 

만약 당신의 절은 더 복잡 WHERE 당신을 대신에 SQLite는 테이블 당 하나의 인덱스만을 사용하기 때문에 복합 인덱스를 만들어야 할 수도 있습니다.따라서 귀하의 경우

CREATE INDEX MyTableFirstSecond ON MyTable(First,Second); 

:

  1. 맥 위에 데이터베이스를 가져옵니다.
  2. 셸을 사용하여 느린 쿼리를 진단하십시오.
  3. 쿼리가 느린 이유를 확인하십시오. 인덱싱해야하는 항목은 무엇입니까? 그리고 덜 가능성 : 쿼리는 어색합니까, 쿼리 최적화 프로그램이 합리적인 계획을 선택하지 못하게합니까?
  4. 적절한 인덱스를 추가하거나 쿼리를 조정하십시오.
  5. 변경 사항이 적용되었는지 다시 테스트하십시오.

SQLite의 경험 법칙은 간단합니다. 검색하려면 인덱스해야합니다.

관련 문제