iOS-цель C: как оптимизировать SQL-запрос - PullRequest
0 голосов
/ 23 мая 2018

В моем приложении для iOS я добавил следующий код, который проверит наличие данных в базе данных.Если да, обновите эту запись, в противном случае вставьте новую запись.

- (void)saveRoomsToDB:(NSArray *)room{
    NSString *dbpath = [[self documentDirectoryPath] stringByAppendingFormat:@"/"databaseName];

    database = [FMDatabase databaseWithPath:dbpath];

    if([database open]){
        [database beginTransaction];

        for (Room *roomData in room) {
            FMResultSet *result = [database executeQuery:@"SELECT RoomDesc FROM Room WHERE QMSRoomId = ?" withArgumentsInArray:@[@(roomData.RoomId)]];

            if ([result next]){
                [database executeUpdate:@"UPDATE Room SET QMSSubSectionId = ?,RoomDesc = ?,LastEditedDate = ?,RoomType = ?, isTrue = ?, CyclePerformed = ? WHERE QMSRoomId = ?" withArgumentsInArray:@[@(roomData.QMSSubSectionId), roomData.RoomDesc, roomData.LastEditDate, roomData.rt_description, @(roomData.isTrue), @(roomData.CyclePerformed), @(roomData.RoomId)]];
            } else{
                [database executeUpdate:@"INSERT INTO Room (QMSSubSectionId, QMSRoomId,RoomDesc, LastEditedDate, RoomNumber,RoomType, CyclePerformed,isTrue) VALUES (?, ?, ?, ?, ?, ?, ?, ?);" withArgumentsInArray:@[@(roomData.QMSSubSectionId), @(roomData.RoomId), roomData.RoomDesc, roomData.LastEditDate, roomData.RoomNumber, roomData.rt_description, @(roomData.CyclePerformed), @(roomData.isTrue)]];
            }
        }

        [database commit];
        [database close];
    }
}

Я распечатал журнал для выполнения вышеуказанного запроса в виде,

2018-05-23 17:47: 49.702 SterileTrakks [656: 74128] нет записей для комнат: 7136
2018-05-23 17: 48: 07.153 SterileTrakks [656: 74128] Вставка для комнат завершена`

МожетЯ оптимизирую это время вставки запроса?Я думаю о применении индексации, но есть ли другой способ?

Ответы [ 2 ]

0 голосов
/ 24 мая 2018

необходимо использовать OOPs Concept

FMResultSet *rs = [MyModel selectQuery:strquery];

            while ([rs next]) {

            }

////Store Responce DATA IN DaTABASE
 for (int i=0; i<(unsigned long)[responseObject count]; i++) {
                progVal++;
                [MyModel insertInto_papertype:[responseObject objectAtIndex:i] :tableName];
            }


///////////////INSERT DATA METHOD/////////////////////////
+(void)insertInto_papertype:(NSMutableDictionary *)mdict :(NSString *)tblnm
{
    NSLog(@"--%@",mdict);
    NSString *insertQuery=@"", *keyQuery = @"", *valueQuery=@"";
    NSString * numberReg = @"[0-9]";

    NSPredicate * numberCheck = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", numberReg];

    if([mdict count] > 0) {
        insertQuery = [NSString stringWithFormat:@"Insert into %@ (",tblnm];

        for(id key in mdict) {
            NSString *repalcedString =  [mdict valueForKey:key];

            if (![numberCheck evaluateWithObject:repalcedString]){
                @try {
                    if ([repalcedString rangeOfString:@"\'"].location != NSNotFound) {
                        repalcedString =  [repalcedString stringByReplacingOccurrencesOfString:@"\'" withString:@"\''"];
                    }
                }
                @catch (NSException *exception) {
                    NSLog(@"%@", exception.reason);
                }
                @finally {

                }
            }
            if([keyQuery isEqualToString:@""]){
                keyQuery = [NSString stringWithFormat:@"%@,",key];

                valueQuery = [NSString stringWithFormat:@" \' %@ \' ,",repalcedString];

            } else {
                keyQuery = [NSString stringWithFormat:@"%@ %@,",keyQuery,key];
                valueQuery = [NSString stringWithFormat:@"%@ \' %@ \' ,",valueQuery,repalcedString];
            }
        }


        //// removing extra , at end;
        keyQuery = [keyQuery substringToIndex:keyQuery.length-(keyQuery.length>0)];
        valueQuery = [valueQuery substringToIndex:valueQuery.length-(valueQuery.length>0)];

        //// adding remaining ) at end
        keyQuery = [NSString stringWithFormat:@"%@ )",keyQuery];
        valueQuery = [NSString stringWithFormat:@"%@ )",valueQuery];

        //// joinng the key and values for insert
        insertQuery = [NSString stringWithFormat:@"%@ %@ values (%@",insertQuery,keyQuery,valueQuery];
        NSLog(@"URL --%@",insertQuery);
        [self UpdateQuery:insertQuery];
    }


}

Если какой-либо запрос поставить на поле для комментариев.

0 голосов
/ 23 мая 2018

Индексирование улучшит время SELECT, но замедлит вставку.В целом, хорошая идея иметь индексы для первичных ключей, таких как QMSRoomId.

Вы можете оптимизировать часть SELECT, переместив выражение SELECT за пределы цикла, и вместо 7000 SELECT сделайте только один выбор заранеечтобы получить набор существующих комнат.Вам не следует запрашивать RoomDesc, а запрашивать SELECT QMSRoomId FROM Room, что может быть быстрее.Затем поместите все идентификаторы в NSSet или отсортированный NSArray для быстрого поиска в цикле.Обратите внимание, что для такого запроса вам не нужны никакие индексы.

Чтобы оптимизировать цикл INSERT, вы можете выполнять пакетную вставку вместо вставки одной записи (см. Можно ли вставлять несколько строк одновременнов базе данных SQLite? ).Другая оптимизация - отключение индексов при вставке большого количества материала (и повторное включение после него).

Другая вещь, которая может помочь, - это разделение UPDATE.Если у вас есть всего несколько обновлений, лучше делать их отдельно.Если у вас много обновлений, на самом деле лучше загрузить полную таблицу, удалить ее и перезагрузить с нуля (без обновлений).

Вы должны измерить каждый шаг вашего алгоритма, чтобы понять, какая часть является самой медленной.

Более общий совет с этим кодом, который вы должны задать себе, - действительно ли вам нужно вставить 7000 записей водин раз?Было бы хорошо, если бы это было действие пользователя (например, попытка импортировать огромный файл данных в пользовательском интерфейсе), но тогда отчасти ожидаемое время.Если это делается для целей кэширования, вы можете хранить этот кеш в памяти и вставлять его в базу данных асинхронно по частям, чтобы он не влиял на UX.Также для кеширования я бы посоветовал не использовать базу данных SQL полностью, особенно кеширование только для чтения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...