2015-12-22 2 views
2

Как повысить производительность вставки данных в SQLite Database.iOS - улучшенная производительность вставки SQLite

Объем данных 30000 записей. Кодекс:

- (void)insertBranchDB:branchlistArray 
{ 
const char *dbpath = [databasePath UTF8String]; 

if (sqlite3_open(dbpath, &database) == SQLITE_OK) 
{ 
    int count = 0; 
    for (Branch *branch in branchlistArray) { 
     NSString *insertSQL = [NSString stringWithFormat: 
           @"insert or replace into Branch (id, lang, lat, lng, province_id, district_id, optional, bus, status, name, address, contact, telephone, remark, province_name, district_name, lastupdate) values (\"%@\", \"%@\", \"%@\", \"%@\",\"%@\", \"%@\", \"%@\", \"%@\",\"%@\", \"%@\", \"%@\", \"%@\",\"%@\", \"%@\", \"%@\", \"%@\", \"%@\")",branch._id,branch.lang,branch.lat,branch.lng,branch.province_id,branch.district_id,branch.optional,branch.bus,branch.status,branch.name,branch.address,branch.contact,branch.telephone,branch.remark,branch.province_name,branch.district_name,branch.lastupdate]; 
     const char *insert_stmt = [insertSQL UTF8String]; 
     sqlite3_prepare_v2(database, insert_stmt,-1, &statement, NULL); 
     if (sqlite3_step(statement) == SQLITE_DONE) { 
      NSLog(@"Completed to Add Branch %d",count); 
      count; 
     } 
     else { 
      NSLog(@"Failed to Add Branch %d",count); 
      count; 
     } 
    } 
    sqlite3_finalize(statement); 
    sqlite3_close(database); 
    } 
} 
+0

Вы можете переместить определение 'insertSQL' и присвоить' insert_stmt' вне цикла. Это означало бы использование заполнителей для значений («?») И заполнение их внутри цикла, используя семейство функций «sqlite3_bind_ *». – Avi

+0

Точка Ави может иметь скромное влияние на производительность (существенная экономия при использовании транзакций), но вы должны принять его шаблон по другим причинам. В частности, использование '?' Placeholder в вашем SQL, а затем использование 'sqlite3_bind_xxx()' для привязки значений намного безопаснее и надежнее. Если кто-то попытался вставить значение, которое, собственно, содержало двойную кавычку, ваш существующий SQL не удался. Использование 'sqlite3_bind_xxx()' решит эту проблему. И, как говорит Ави, если вы «подготовитесь» один раз, а затем «привяжите», «шаг» и «перезагрузите» для каждого цикла, он также будет скромно более эффективным. – Rob

+0

Кстати, если вы обнаружите, что вызов 'sqlite3_bind_xxx()' для каждого из этих столбцов немного громоздкий, вы можете использовать что-то вроде [FMDB] (https://github.com/ccgus/fmdb), что может упростить этот процесс. – Rob

ответ

-2

Посмотрите вставить строки в объеме

INSERT INTO 'tablename' 
SELECT 'data1' AS 'column1', 'data2' AS 'column2' 
UNION ALL SELECT 'data1', 'data2' 
UNION ALL SELECT 'data1', 'data2' 
UNION ALL SELECT 'data1', 'data2' 

Так что в вашем случае:

INSERT INTO 'Branch' 
SELECT 'id' AS 'column1', 'lang' AS 'column2' 
UNION ALL SELECT 'row_one_.branch._id', 'row_one_.branch.lang' 
UNION ALL SELECT 'row_two_.branch._id', 'row_two_.branch.lang' 
UNION ALL SELECT 'row_three_.branch._id', 'row_three_.branch.lang' 

взгляд на этот пост Is it possible to insert multiple rows at a time in an SQLite database?

+0

Это не работает более 500 строк. –

+0

Затем выполните цикл до 500, затем выполните команду, затем скомпилируйте следующие 500 и т. Д. – Reedy

1

Глядишь резкое улучшение производительности, если вы используете транзакции. Поэтому, прежде чем выполнять все операторы INSERT, выполните BEGIN TRANSACTION и в конце выполните COMMIT (или COMMIT TRANSACTION или END TRANSACTION).

См. Обсуждение Transactions на http://sqlite.org.

Смежные вопросы