针对大数据的CoreData优化

时间:2014-06-10 12:42:56

标签: ios iphone xcode core-data

块中的提取请求花费大约9分钟来处理仪器上的处理customerArray有大约60K个对象,而CusCustomerAddress Model有大约30k个对象,所以我必须优化这个时间。

   NSArray *customerArray=[engine getItemsForEntity:@"CusCustomer" predicate:nil error:nil];
        NSPredicate *predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"id1 == $idVar"]];
        NSPredicate *predicateCustomerAddress = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"customerId == $customerIdVar AND addressType == $addressTypeVar"]];

    [customerArray enumerateObjectsUsingBlock:^(CusCustomer *customer, NSUInteger idx, BOOL *stop) {            
        NSString *customerId=customer.id1;
        NSString *addressType = ShippingAddress;
        NSDictionary *variablesAddress = @{ @"customerIdVar" : customerId , @"addressTypeVar" : addressType};
        NSArray *resultAddress = [engine getItemsForEntity:@"CusCustomerAddress" predicate:[predicateCustomerAddress        predicateWithSubstitutionVariables:variablesAddress] error:nil];
        if (resultAddress.count == 1 ) {
            [customer addCustomerAddressObject:(CusCustomerAddress *)[resultAddress lastObject]];
        }
        else
        {
            DLogHp(@"More than one tuple Exist For  this'id1' =\"%@\" in \"CusCustomerGroup\"",objId);
        }
        addressType = BillingAddress;
        NSDictionary *variablesAddress1 = @{ @"customerIdVar" : customerId , @"addressTypeVar" : addressType};

        NSArray *resultaddress1 = [engine getItemsForEntity:@"CusCustomerAddress" predicate:[predicateCustomerAddress predicateWithSubstitutionVariables:variablesAddress1] error:nil];

        if (resultaddress1.count == 1 ) {
            [customer addCustomerAddressObject:(CusCustomerAddress *)[resultaddress1 lastObject]];
        }
        else
        {
            DLogHp(@"More than one tuple Exist For  this'id1' =\"%@\" in \"CusCustomerGroup\"",objId);
        }
    }];

}

1 个答案:

答案 0 :(得分:5)

这可能是从Core Data(或任何数据库)检索数据的最昂贵的方式。您正在有效地创建N个提取而不是构建单个查询。

考虑将您的逻辑更改为:

  1. 通过KVC将customerIDs转换为数组:

    NSArray * ids = [customerArray valueForKey:@“id1”];

  2. 获取具有谓词的客户的所有送货地址:

    [NSPredicate predicateWithFormat:@“addressTypeVar ==%@&& customerIdVar IN%@”,ShippingAddress,ids]; NSArray * shippingResults = ...;

  3. 根据customerID将该获取的结果转换为字典

    NSDictionary * shippingAddresses = [NSDictionary dictionaryWithObjects:shippingResults forKeys:[shippingResults valueFOrKey:@“customerIdVar”];

  4. 迭代您的客户数组并关联送货地址:

    for(customerArray中的id customer){   [customer addCustomerAddressObject:[shippingAddresses [customer.id1]]]; }

  5. 重复营业地址

  6. 我不得不说,这是相当倒退的。理想情况下,您应该在导入或创建数据时创建这些关系。在数据已经存储在商店中之后执行此操作效率很低。

    其他几点:

    • 如果方法返回id,则无需强制转换。演员只会添加噪音,将其删除。
    • 你的变量名称粗糙。我建议删除“Var”,因为它是多余的
    • 考虑批量提取,因为此过程会导致一些重大的内存问题。无论如何,60K记录都会很昂贵。
    • 做谓词时,便宜到昂贵。现在你的谓词中有字符串比较。那是最贵的。如果您可以更改数据模型,请将地址类型更改为整数。数字比较便宜得多。