バッチ サイズは、一度に取得するオブジェクトの数を示しています。これはおそらくあまり役に立たないでしょう。ユースケースを少し考えてみましょう...
ユーザーが「F」と入力し、データベースに「'F' で始まるすべての名前を見つけてください」と指示すると、データベースは 10,000 件以上のすべてのレコードを調べて、'F' で始まる名前を見つけます。
次に、ユーザーが「r」と入力すると、「Fr」で始まるすべてのレコードを検索するようにデータベースに指示し、「Fr」で始まるレコードを検索するために 10,000 件以上のすべてのレコードを再度検索します。
fetchBatchSize が行っているのは、「ねえ、レコードに失敗したときは、一度に 50 を持ってきてください。いずれにせよ、おそらくそれらすべてが必要になるからです」と伝えるだけです。それはあなたの検索を制限するものではありません。
ただし、fetchLimit を 100 に設定すると、データベースが 10,000 件以上のすべてのレコードの検索を開始するため、ある程度は役立ちますが、100 件のレコードを取得すると、要求が既に満たされているため、残りのレコードを調べ続ける必要はありません。完了し、要求を満たす 100 レコードを取得するとすぐに検索を停止します。
そのため、他のユースケースに応じて、できることがいくつかあります。
最も簡単な方法は、検索しているフィールドにインデックスを追加することです。これは、Xcode モデル エディターで設定できます (インスペクターでエンティティに名前を付けることができる場所のすぐ下にある [インデックス] というセクション)。これにより、データベースはそのフィールドに特別なインデックスを設定できるようになり、検索がはるかに高速になります。
第二に、最初のリクエストの後、すでに「F」で始まる名前の配列があるため、データベースに戻って「Fr」で始まる名前を尋ねる必要はありません。「Fr」で始まる場合も「F」で始まり、それらすべての NSManagedObject ポインターが既にあります。これで、返された配列を検索できます。
さらに良いことに、並べ替え記述子を指定すると、配列は並べ替えられます。したがって、配列に対して単純な二分探索を行うことができます。または、必要に応じて、同じ述語を使用して、データベースの代わりに結果配列に適用することもできます。
先ほど説明した結果のプルーニングを使用しなくても、属性のインデックス作成は劇的に改善すると思います。
編集
計測器を実行して、どこでどれだけの時間を費やしているかを確認する必要があるかもしれません。また、述語の形式が不適切な場合、インデックス スキームが機能しなくなる可能性があります。コードが役立ちます。
最後に、メモリに取り込む要素の数を検討してください。CoreData はすべての情報をフォールトするわけではありませんが、アレイ内のすべての情報に対してシェルを作成します。
ソート述語を与えると、
SQLLite がインデックスに検索を実装する方法はわかりませんが、B ツリーには複雑な logBN があるため、30k レコードであっても、検索はそれほど多くありません。別の問題がない限り、インデックス作成によってかなり大きな改善が得られるはずです。
インデックスを取得したら、すべてのレコードを調べる必要はありません。ただし、まだ非常に大きなデータ セットがある場合があります。フェッチされるレコードの数を制限し、残りのプロキシを作成するため、それらに対して fetchBatchSize を試してください。
また、executeFetchRequest の代わりに countFetchRequex を呼び出して、アイテムの数を取得することもできます。次に、fetchLimit を使用して、取得する数を制限できます。
フェッチされた結果コントローラでこれらすべてを操作する限り...まあ、その人はレコードを知っている必要があるため、検索を行う必要があります。
また、1 つの場所を参照してください... セクションを行っていますか? 何か (セクションの翻訳など) に対してユーザー定義のコンパレータがある場合、これはすべてのレコードに対して呼び出されます。
したがって、インデックスの変更を行った後の私の大きな提案は、機器を実行し、それを実際に調べて、どこに時間を費やしているかを判断することだと思います. それはかなり明白なはずです。それは、あなたを本当の問題に導くのに役立ちます。
私の賭けは、何らかの理由でまだすべての要素にアクセスしているということです...