Tôi đang làm việc trên ứng dụng học tập kiểu thẻ flash iOS, khi đang tải, cần lấy một loạt dữ liệu từ Dữ liệu chính. Nhưng dữ liệu tôi cần là một tập hợp con khá cụ thể của thực thể, dựa trên cài đặt người dùng, do đó, có nhiều vị từ liên quan đến việc kiểm tra tính tương đương. Tôi đang tìm thấy những tìm nạp là siêu chậm và, dựa trên nghiên cứu về SQLite, tôi nghĩ rằng một chỉ số sẽ là một lựa chọn tốt ở đây.Có thể lập chỉ mục phức tạp khi sử dụng Dữ liệu chính không?
Bây giờ, tôi hiểu (phần lớn là đọc các câu hỏi về lưu lượng truy cập stackover khác) rằng Dữ liệu SQLite và Core là hai thứ khác nhau, về cơ bản trực giao mà không nên nhầm lẫn. Nhưng nó cũng là sự hiểu biết của tôi rằng bạn đang phải làm việc thông qua Core Data để làm bất kỳ loại công việc cơ sở dữ liệu và tinh chỉnh; bạn không nên bỏ qua và làm việc trực tiếp với SQLite khi tối ưu hóa hoặc thiết kế đối tượng lâu dài trong ứng dụng của bạn.
Nhưng điều duy nhất tôi có thể tìm thấy các chỉ mục trong Dữ liệu chính là hộp kiểm "được lập chỉ mục" cho mỗi thuộc tính trong một mô hình. Và đó không phải là loại tối ưu mà tôi đang tìm kiếm.
Đây là yêu cầu lấy, hiện:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"SKUserItem" inManagedObjectContext:context];
fetchRequest.entity = entity;
NSSortDescriptor *sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"next" ascending:YES] autorelease];
fetchRequest.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSMutableArray *predicates = [NSMutableArray arrayWithCapacity:6];
[predicates addObject:[NSPredicate predicateWithFormat:@"next < %f", now() + (60.0*60.0*24.0)]];
[predicates addObject:[NSPredicate predicateWithFormat:@"next > %f", nextOffset]];
[predicates addObject:[NSPredicate predicateWithFormat:@"user == %@", user]];
[predicates addObject:[NSPredicate predicateWithFormat:@"langRaw == %d", lang]];
NSArray *stylePredicates = [NSArray arrayWithObjects:[NSPredicate predicateWithFormat:@"styleRaw == %d", SK_SIMP_AND_TRAD], [NSPredicate predicateWithFormat:@"styleRaw == %d", self.style], nil];
[predicates addObject:[NSCompoundPredicate orPredicateWithSubpredicates:stylePredicates]];
if([self.parts count] == 4 || (self.lang == SK_JA && [self.parts count] == 3))
; // don't have to filter by parts; they're studying all of them
else {
NSMutableArray *partPredicates = [NSMutableArray arrayWithCapacity:[self.parts count]];
for(NSString *part in self.parts)
[partPredicates addObject:[NSPredicate predicateWithFormat:@"partRaw == %d", partCode(part)]];
[predicates addObject:[NSCompoundPredicate orPredicateWithSubpredicates:partPredicates]];
}
NSPredicate *compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:predicates];
fetchRequest.predicate = compoundPredicate;
Vì vậy, về cơ bản những gì này lấy làm là sắp xếp theo tiếp theo (thời gian khi mặt hàng nhất định là do) và bộ lọc cho tên người dùng, ngôn ngữ đang được nghiên cứu, phong cách con người nghiên cứu (bằng tiếng Trung Quốc có đơn giản và truyền thống) và các phần đang được nghiên cứu (viết, giai điệu, đọc hoặc định nghĩa) và chỉ tìm nạp trong phạm vi "tiếp theo". Dưới đây là danh sách ngắn về những điều tôi đã học được từ việc chỉnh sửa và không quan tâm đến điều này:
- Nó luôn quét toàn bộ bảng hoặc dường như. Mặc dù tiếp theo được lập chỉ mục, ngay cả khi tôi buộc nó phải tìm kiếm một phạm vi mà tôi biết sẽ không trả về gì, nó vẫn mất vài giây để tìm nạp hoàn tất.
- Các biến vị ngữ, bất kỳ số lượng vị từ nào, làm cho điều này chậm. Nếu tôi loại bỏ một số nhưng không phải tất cả, nó là về chậm. Nếu tôi loại bỏ tất cả các vị từ (do đó phá vỡ các ứng dụng) sau đó nó nhanh hơn nhiều.
- Tốc độ phụ thuộc nhiều vào số lượng UserItems có tổng trong bảng. Càng có nhiều vật phẩm thì càng chậm. Một số người có thể có hàng chục nghìn mặt hàng và đó là khi việc tìm nạp này có thể mất tới 10 giây để hoàn thành. Điều này dẫn đến tạm dừng vụng về trong ứng dụng của tôi.
- Giới hạn trên của giá trị tiếp theo đã được thêm vào không phải vì chúng tôi cần nó, mà vì nó tăng tốc độ tìm nạp một chút.
- Có truy vấn trả về tập hợp con các thuộc tính trong từ điển (chứ không phải là toàn bộ đối tượng được quản lý) và tìm nạp phần còn lại một cách lười biếng, nhưng vẫn chưa đủ nhanh hơn.
Tôi đến từ Google App Engine ở đây, vì vậy tôi đã quen với các chỉ mục mà họ cung cấp ở đó. Về cơ bản tôi muốn loại chỉ mục đó, nhưng được áp dụng cho SQLite thông qua Core Data. Tôi tìm thấy thông tin về việc thêm các chỉ mục trong SQLite, loại mà tôi muốn, nhưng thực hiện kiểu lập chỉ mục này thông qua Core Data, tôi không thể tìm thấy bất kỳ thông tin nào về điều đó.
Tôi chưa gặp sự cố về hiệu suất với Dữ liệu cốt lõi hiển thị với 1 biến vị ngữ, nhưng nếu bạn chỉ nói về hàng chục nghìn mục, bạn có thể tìm thấy hiệu suất tốt hơn bằng cách sử dụng kho dữ liệu lõi không dựa trên sql. Ví dụ, kiểu lưu trữ nhị phân có thể nhanh hơn. –
Cảm ơn bạn đã đề xuất. Tôi đã thử nó nhưng nó xuất hiện, thử nghiệm trên 3GS của tôi, rằng các loại lưu trữ nhị phân không thể xử lý nhiều dữ liệu. Tôi nhận được nửa chừng tải một tài khoản với hơn 30,000 mục trước khi chương trình bị lỗi do sử dụng quá nhiều bộ nhớ. Có lẽ vì có 26 thuộc tính trong thực thể SKUserItem. –
Ah, quá tệ rồi. Tôi thực sự không hiểu tại sao điểm # 1 là trường hợp nếu thuộc tính được lập chỉ mục. –