Как улучшить Базовую производительность Данных?

Мое приложение имеет UISearchBar, разрешающий пользователю ввести поисковые ключевые слова. Каждое нажатие клавиши выполняет Базовый Запрос данных для отображения результатов как текста в изменениях панели поиска.

Проблема состоит в том, что нажатия клавиш панели поиска отстают довольно плохо..., конечно, из-за медленной выборки. Какие-либо идеи, как улучшить производительность?

Мои Базовые Данные поддерживаются sqlite хранилищем данных, которое содержит 1 000 объектов.

// searchKeyword is the string appears in UISearchBar
// Both title and author may contain several words so I can't use BEGINSWITH
NSPredicate* predicate = [NSPredicate predicateWithFormat:@"(author CONTAINS[c] %@) OR (title CONTAINS[c] %@)", searchKeyword, searchKeyword];

NSEntityDescription* entity = [NSEntityDescription entityForName:@"Book" inManagedObjectContext:managedObjectContext];

NSFetchRequest* request = [[NSFetchRequest alloc] init];
[request setEntity:entity];
[request setPredicate:predicate];
[request setFetchLimit:10];

NSSortDescriptor* sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"title" ascending:YES];
NSArray* sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];

[sortDescriptor release];
[sortDescriptors release];

execute request and fetch the results
fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
                                managedObjectContext:managedObjectContext
                                sectionNameKeyPath:nil
                                cacheName:nil];
NSError* error = nil;
BOOL success = [fetchedResultsController performFetch:&error];
[request release];
14
задан Joshua 15 August 2010 в 20:46
поделиться

5 ответов

Использование CONTAINS замедляет его. Что вам нужно сделать, так это создать новую таблицу с именем searchWords (или что-то еще), и в ней хранить все слова в ваших заголовках, сделанные в нижнем регистре и с удаленными диакритическими знаками. У них есть отношения, связывающие их обратно с исходными объектами. Убедитесь, что поле слова проиндексировано.

Выполните запрос к этой таблице, но вместо использования CONTAINS или BEGINSWITH выполните что-то вроде

word> "term" AND word <"tern"

Обратите внимание, что первая строка в этой строке - это поисковый запрос, а второй - это поисковый запрос с увеличенным последним символом. Это позволяет Core Data использовать индекс SQL для выполнения поиска.

У Apple есть сеанс WWDC Core Data , который объясняет это, включая пример кода. Пример кода содержит класс, который обрабатывает нормализацию строки (т. Е. Удаление регистра) и увеличивает последний символ слова с учетом Unicode.

18
ответ дан 1 December 2019 в 07:27
поделиться

Хотя это не ускорит запрос, размещение поиска в фоновом потоке остановит запаздывание нажатий клавиш.

4
ответ дан 1 December 2019 в 07:27
поделиться

Вы можете создать дерево постепенно, чтобы иметь индекс для прошлых запросов (наборы результатов указываются конечными узлами). но это не повысит производительность отдельного запроса. Вы также можете настроить систему нажатия клавиш, не выполняйте выборку после каждого нажатия клавиши, а только после нажатия клавиши, после которого проходит временной интервал (в качестве порога), прежде чем будет распознано еще одно нажатие клавиши

2
ответ дан 1 December 2019 в 07:27
поделиться

При запуске приложения создайте полное дерево и адаптируйте его при редактировании. Не используйте этот дурацкий предикат. Вы получаете только 1000 записей, так что это не займет времени.

-1
ответ дан 1 December 2019 в 07:27
поделиться

Хотя рекомендация Амойры разумна, у вас также есть проблема с дизайном.

Только первая буква, введенная в поле поиска, должна когда-либо попасть на диск. После первой буквы вы должны уточнять результаты поиска только по тому, что уже находится в памяти.

Вы должны фильтровать массив, который находится в памяти (из поиска по первой букве), используя предикат, который у вас уже есть, и избегать выполнения запроса на выборку, поскольку это не нужно.

Вдобавок, если вы собираетесь искать данные, которые уже находятся в памяти (например, живущие в NSFetchedResultsController ), то весь ваш поиск должен касаться только объектов в памяти. Выходить на диск не нужно, и это ужасно расточительно.

13
ответ дан 1 December 2019 в 07:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: