Kết luận
Sự cố đã đóng, tôi nghĩ vậy.
Có vẻ như vấn đề không liên quan gì đến phương pháp luận, nhưng XCode không làm sạch dự án một cách chính xác giữa các bản dựng.
Dường như sau tất cả các thử nghiệm đó, tệp sqlite đã được sử dụng vẫn là tệp đầu tiên không được lập chỉ mục ......
Cẩn thận với XCode 4.3.2, tôi không có gì ngoài vấn đề với Sạch không làm sạch, hoặc thêm các tập tin dự án không tự động được thêm vào các nguồn tài nguyên bó ...
Cảm ơn câu trả lời khác nhau ..Cách nhanh nhất để tải tệp CSV lớn vào dữ liệu chính là gì
cập nhật 3
Kể từ khi tôi mời ai chỉ cần thử các bước tương tự để xem nếu họ nhận được kết quả tương tự, hãy để tôi chi tiết những gì tôi đã làm:
Tôi bắt đầu với dự án trống
tôi xác định một DataModel với một Entity, 3 thuộc tính (2 dây, 1 phao)
Chuỗi đầu tiên được lập chỉ mục
Trong đã finishLaunchingWithOptions, tôi kêu gọi:
[self performSelectorInBackground:@selector(populateDB) withObject:nil];
Mã cho populateDb bên dưới:
-(void)populateDB{
NSLog(@"start");
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
NSManagedObjectContext *context;
if (coordinator != nil) {
context = [[NSManagedObjectContext alloc] init];
[context setPersistentStoreCoordinator:coordinator];
}
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"input" ofType:@"txt"];
if (filePath) {
NSString * myText = [[NSString alloc]
initWithContentsOfFile:filePath
encoding:NSUTF8StringEncoding
error:nil];
if (myText) {
__block int count = 0;
[myText enumerateLinesUsingBlock:^(NSString * line, BOOL * stop) {
line=[line stringByReplacingOccurrencesOfString:@"\t" withString:@" "];
NSArray *lineComponents=[line componentsSeparatedByString:@" "];
if(lineComponents){
if([lineComponents count]==3){
float f=[[lineComponents objectAtIndex:0] floatValue];
NSNumber *number=[NSNumber numberWithFloat:f];
NSString *string1=[lineComponents objectAtIndex:1];
NSString *string2=[lineComponents objectAtIndex:2];
NSManagedObject *object=[NSEntityDescription insertNewObjectForEntityForName:@"Bigram" inManagedObjectContext:context];
[object setValue:number forKey:@"number"];
[object setValue:string1 forKey:@"string1"];
[object setValue:string2 forKey:@"string2"];
NSError *error;
count++;
if(count>=1000){
if (![context save:&error]) {
NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
}
count=0;
}
}
}
}];
NSLog(@"done importing");
NSError *error;
if (![context save:&error]) {
NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
}
}
}
NSLog(@"end");
}
Mọi thứ khác là mã dữ liệu cốt lõi mặc định, không có gì được thêm vào.
Tôi chạy điều đó trong trình mô phỏng.
tôi đi đến ~/Library/Application Support/iPhone Simulator/5.1/Applications // Documents
Có file sqlite được tạo
Tôi lấy điều đó và tôi sao chép nó trong bó của tôi
tôi bình luận ra lời kêu gọi populateDb
tôi sửa persistentStoreCoordinator để sao chép các tập tin SQLite từ bó với các tài liệu tại chạy đầu tiên
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
@synchronized (self)
{
if (__persistentStoreCoordinator != nil)
return __persistentStoreCoordinator;
NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:@"myProject" ofType:@"sqlite"];
NSString *storePath = [[[self applicationDocumentsDirectory] path] stringByAppendingPathComponent: @"myProject.sqlite"];
NSError *error;
if (![[NSFileManager defaultManager] fileExistsAtPath:storePath])
{
if ([[NSFileManager defaultManager] copyItemAtPath:defaultStorePath toPath:storePath error:&error])
NSLog(@"Copied starting data to %@", storePath);
else
NSLog(@"Error copying default DB to %@ (%@)", storePath, error);
}
NSURL *storeURL = [NSURL fileURLWithPath:storePath];
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error])
{
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return __persistentStoreCoordinator;
}
}
Tôi xóa ứng dụng khỏi trình mô phỏng, tôi kiểm tra xem ~/Library/Application Support/iPhone Simulator/5.1/Applications/hiện đã bị xóa
Tôi tạo lại và khởi chạy lại
Như dự kiến, tệp sqlite được sao chép sang ~/Library/Hỗ trợ ứng dụng/Trình mô phỏng iPhone/5.1/Ứng dụng // Tài liệu
Tuy nhiên kích thước của tệp nhỏ hơn trong gói, đáng kể! Ngoài ra, thực hiện truy vấn đơn giản với biến vị ngữ như vị từ này = [NSPredicate predicateWithFormat: @ "string1 ==% @", string1]; rõ ràng cho thấy rằng chuỗi1 không lập chỉ mục nữa
Sau đó, tôi tạo ra một phiên bản mới của DataModel, với một bản cập nhật vô nghĩa, chỉ để buộc một sự chuyển đổi nhẹ
Nếu chạy trên giả lập, sự di cư mất vài giây, cơ sở dữ liệu tăng gấp đôi về kích thước và cùng một truy vấn bây giờ mất ít hơn một giây để trở về thay vì phút.
Điều này sẽ giải quyết được vấn đề của tôi, buộc phải di chuyển, nhưng việc di chuyển đó mất 3 phút trên iPad và xảy ra ở nền trước.
Vì vậy, mũ của tôi đang ở ngay bây giờ, giải pháp tốt nhất cho tôi sẽ vẫn là để ngăn chặn các chỉ mục được loại bỏ, bất kỳ giải pháp nhập khẩu khác lúc khởi động chỉ mất quá nhiều thời gian.
Hãy cho tôi biết nếu bạn cần thêm làm rõ ...
Cập nhật 2
Vì vậy, kết quả tốt nhất mà tôi đã có cho đến nay là để gieo rắc các cơ sở dữ liệu dữ liệu cốt lõi với các tập tin SQLite được sản xuất từ một công cụ nhanh chóng với tương tự mô hình dữ liệu, nhưng không có các chỉ mục được thiết lập khi tạo tệp sqlite. Sau đó, tôi nhập tệp sqlite này vào ứng dụng dữ liệu lõi với các chỉ mục được đặt và cho phép di chuyển nhẹ. Đối với 2 triệu bản ghi trên iPad mới, thời gian di chuyển này mất 3 phút. Ứng dụng cuối cùng phải có gấp 5 lần số lượng hồ sơ này, vì vậy chúng tôi vẫn đang xem xét thời gian xử lý dài. Nếu tôi đi tuyến đường đó, câu hỏi mới sẽ là: có thể thực hiện di chuyển nhẹ trong nền không?
Cập nhật
Câu hỏi của tôi là không làm thế nào để tạo ra một công cụ để cư một cơ sở dữ liệu Core Data, và sau đó nhập tệp sqlite vào ứng dụng của tôi.
Tôi biết làm thế nào để làm điều này, tôi đã làm nó vô số lần.
Nhưng cho đến bây giờ, tôi đã không nhận ra rằng phương pháp như vậy có thể có một số tác dụng phụ: trong trường hợp của tôi, một thuộc tính được lập chỉ mục trong cơ sở dữ liệu kết quả rõ ràng bị 'không lập chỉ mục' khi nhập tệp sqlite theo cách đó.
Nếu bạn có thể xác minh rằng bất kỳ dữ liệu được lập chỉ mục nào vẫn được lập chỉ mục sau khi chuyển, tôi quan tâm để biết cách bạn tiến hành hoặc chiến lược nào tốt nhất để tạo cơ sở dữ liệu hiệu quả như vậy.
gốc
Tôi có một tập tin CSV lớn (hàng triệu dòng) với 4 cột, dây và phao nổi. Tính năng này dành cho ứng dụng iOS.
Tôi cần dữ liệu này được tải vào dữ liệu cốt lõi trong lần đầu tiên ứng dụng được tải.
Ứng dụng này không hoạt động nhiều cho đến khi dữ liệu có sẵn, do đó tải thời gian quan trọng, vì người dùng lần đầu rõ ràng không muốn ứng dụng mất 20 phút để tải trước khi có thể chạy.
Hiện tại, mã hiện tại của tôi mất 20 phút trên iPad mới để xử lý tệp csv 2 triệu dòng.
Tôi đang sử dụng ngữ cảnh nền để không khóa giao diện người dùng và lưu ngữ cảnh mỗi 1.000 bản ghi
Ý tưởng đầu tiên là tạo cơ sở dữ liệu trên trình mô phỏng, sau đó sao chép/dán nó vào thư mục tài liệu lần đầu tiên khởi động, vì đây là cách phổ biến không chính thức của việc tạo một cơ sở dữ liệu lớn. Thật không may, các chỉ mục dường như không tồn tại như một sự chuyển giao, và mặc dù cơ sở dữ liệu đã có sẵn chỉ sau vài giây, hiệu suất là khủng khiếp vì các chỉ mục của tôi đã bị mất. Tôi đã đăng một câu hỏi về các chỉ mục đã có, nhưng dường như không có câu trả lời tốt cho điều đó.
Vì vậy, những gì tôi đang tìm kiếm, hoặc là:
- một cách để cải thiện hiệu suất trên tải hàng triệu bản ghi trong dữ liệu cốt lõi
- nếu cơ sở dữ liệu được nạp sẵn và di chuyển lúc khởi động đầu tiên, một cách để giữ các chỉ mục của tôi
- thực tiễn tốt nhất để xử lý loại kịch bản này.Tôi không nhớ sử dụng bất kỳ ứng dụng nào yêu cầu tôi đợi x phút trước khi sử dụng lần đầu (nhưng có thể The Daily, và đó là một trải nghiệm khủng khiếp).
- Bất kỳ cách sáng tạo nào để người dùng chờ đợi mà không nhận ra điều đó: nhập vào nền trong khi thực hiện hướng dẫn, v.v ...
- Không sử dụng dữ liệu lõi?
- ...
Vậy làm cách nào bạn kết thúc "dọn dẹp" dự án để nó hoạt động chính xác? – lnafziger
Làm sạch không hoạt động, nhưng khởi động lại máy tính xách tay, thủ công làm sạch tất cả các tham chiếu đến tập tin, vv, dường như đã 'giải quyết' vấn đề. lạ ... mặc dù tôi cũng đã phải loại bỏ các dòng di chuyển nhẹ để buộc không di chuyển (vì điều này sẽ mất nhiều phút). Nhìn chung, đây không phải là việc thực hiện sạch sẽ tôi hy vọng, nhưng điều này hoạt động ... cho đến khi một phiên bản 2 cần nâng cấp mô hình dữ liệu, sau đó tôi gặp rắc rối –