Размер партии просто подсказывает, сколько объектов нужно забрать за раз. Скорее всего, это вам не поможет. Давайте рассмотрим ваш случай использования немного ...
Пользователь вводит «F», и вы указываете базу данных: «Идите, найдите все имена, начинающиеся с« F », и база данных просматривает все записи 10k +, чтобы найти которые начинаются с «F»
Затем пользователь вводит «r», поэтому вы указываете базе данных, чтобы найти все записи, которые начинаются с «Fr», и снова просматривает все записи 10k +, чтобы найти те, которые начните с «о.»
Все, что делает fetchBatchSize, говорят ему: «Эй, когда вы ошибаетесь в записи, принесите 50 одновременно, потому что мне все равно понадобится все это». Это не делает ничего, чтобы ограничить ваш поиск.
Однако установка fetchLimit to 100 помогает некоторым, потому что база данных начинает поиск по всем записям 10k +, но после того, как она имеет 100 записей, ей не нужно смотреть на остальные записи, поскольку она уже заполнила свой запрос , Это делается и прекращает поиск, как только он получает 100 записей, удовлетворяющих запросу.
Итак, есть несколько вещей, которые вы можете сделать, все зависит от ваших других случаев использования.
Проще всего попробовать добавить индекс в поле, которое вы ищете. Вы можете установить это в редакторе модели Xcode (раздел, в котором указаны индексы, прямо там, где вы можете назвать объект в инспекторе). Это позволит базе данных настраивать специальный индекс в этом поле, и поиск будет намного быстрее.
Во-вторых, после вашего первоначального запроса у вас уже есть массив имен, начинающихся с «F», поэтому нет необходимости возвращаться в базу данных, чтобы запрашивать имена, начинающиеся с «Fr». Если он начинается с ' Fr 'также начинается с' F ', и у вас уже есть указатели NSManagedObject для всех этих. Теперь вы можете просто найти массив, который у вас есть.
Еще лучше, если вы дали ему дескриптор сортировки, массив отсортирован. Таким образом, вы можете выполнить простой двоичный поиск в массиве. Или, если хотите, вы можете использовать один и тот же предикат и применять его к массиву результатов вместо базы данных.
Даже если вы не используете обрезание результатов, о котором я только что говорил, я думаю, что индексирование атрибута будет значительно увеличиваться.
EDIT
Может быть, вы должны запустить инструменты, чтобы увидеть, сколько времени вы тратите где. Кроме того, плохо сформированный предикат может принести любую кодовую схему индекса. Код поможет.
Наконец, рассмотрите, сколько элементов вы вводите в память. CoreData не отвечает за всю информацию, но создает оболочки для всего массива.
Если вы даете ему сортировать предикат,
Я не знаю, как SQLLite реализует поиск по индексу, а B-Tree имеет сложность logBN, так что даже на 30K записей, это не много поиска , Если у вас нет другой проблемы, индексирование должно было дать вам довольно большое улучшение.
Как только у вас есть индекс, вы не должны изучать все записи. Однако у вас все еще может быть очень большой набор данных. Попробуйте fetchBatchSize на них, потому что это ограничит количество извлеченных записей и создаст прокси для остальных.
Вы также можете вызвать countFetchRequext вместо executeFetchRequest, чтобы получить количество элементов. Затем вы можете использовать fetchLimit для ограничения числа, которое вы получаете.
Что касается работы со всем этим с помощью контролера результатов ... ну, этот парень должен знать записи, поэтому он все равно должен выполнять поиск.
Кроме того, одно место для поиска ... вы занимаетесь секциями? Если у вас есть пользовательский компаратор для чего-либо (например, для переходов для разделов), это будет вызвано для каждой отдельной записи.
Таким образом, я думаю, что мое большое предложение после внесения изменения индекса - запустить инструменты и действительно изучить его, чтобы определить, где вы проводите свое время. Это должно быть довольно очевидно. Это поможет вам справиться с реальной проблемой.
Моя ставка является то, что вы все еще получить доступ ко всем элементам какой-то причине ...
Вы используете запрос с * NSFetchedResultsController *? –
Да. Я использую fetchedresultscontroller из класса Stanford CS193P. – Yan