2009-07-25 3 views
2

Эй, ребята, вот внизу.Проблема с производительностью iPhone Sqlite

У меня есть одна таблица, состоящая из первичного ключа (col1), текста (col2) и текста (col3). В основном карта. Эта таблица содержит около 200 тыс. Строк. В основном мне требуется около 1,1 секунды, чтобы получить одну строку (это все, что я хочу). В основном я использую select * из таблицы, где col2 = 'some value'.

Я попытался создать индекс для всех трех столбцов, каждого столбца индивидуально, и col2 и col3, но это действительно не улучшило мою ситуацию вообще.

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

Любая помощь была бы принята с благодарностью.

+0

Вы уверены, что только одна строка является результатом? – Juergen

+1

Кроме того, я предлагаю использовать инструменты или акулу против вашего приложения, когда он запускает запрос. У меня была аналогичная проблема, и я предполагал, что это SQLite, но оказалось, что это был субоптимальный метод разбора строк в моем коде, который вызывал замедление. –

+0

Да, я уверен, что возвращается только одна строка, я дам акулу попробовать, спасибо за эту идею! – 2009-07-26 00:41:31

ответ

2

Я решил проблему м. Это было то, что когда я создал новый файл базы данных sqlite и добавил его в проект, xcode неправильно перекомпилировал себя, он все еще использовал старый файл. Мне пришлось удалить старую базу данных из проекта, удалить скомпилированную версию на компьютере, очистить проект, затем скомпилировать его и убедиться, что он сбой с момента отсутствия базы данных. Затем снова удалите скомпилированные файлы, очистите их и заново добавьте новую базу данных sqlite.

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

Странно, что это будет рассматриваться как ошибка с Xcode?

+0

Ошибка пользователя. ;) – Sneakyness

2

Я бы сказал, что это абсолютно не типично.

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

Что вы можете сделать: Создайте только один индекс на col2 (это тот, который вам нужен только для этого выбора!).

Чем используется «EXPLAIN SELECT ....», чтобы получить информацию о том, что делает SQLite. Результат непросто прочитать, но с некоторым опытом можно увидеть, используется ли индекс. Вы также можете опубликовать результат здесь.

+0

Это результат объяснения select * из таблицы, где col1 = 'something' 0 | Goto | 0 | 23 | 1 | Целое | 0 | 0 | 2 | OpenRead | 0 | 2 | 3 | SetNumColumns | 0 | 3 | 4 | Целое | 0 | 0 | 5 | OpenRead | 1 | 4 | keyinfo (1, BINARY) 6 | String8 | 0 | 0 | 1 7 | IsNull | -1 | 20 | 8 | Сделать заказ | 1 | 0 | a 9 | MemStore | 0 | 0 | 10 | MoveGe | 1 | 20 | 11 | MemLoad | 0 | 0 | 12 | IdxGE | 1 | 20 | + 13 | IdxRowid | 1 | 0 | 14 | MoveGe | 0 | 0 | 15 | Колонка | 0 | 0 | 16 | Колонка | 0 | 1 | 17 | Колонка | 0 | 2 | 18 | Обратный звонок | 3 | 0 | 19 | Следующая | 1 | 11 | 20 | Закрыть | 0 | 0 | 21 | Закрыть | 1 | 0 | 22 | Остановка | 0 | 0 | 23 | Сделки | 0 | 0 | 24 | VerifyCookie | 0 | 3 | 25 | Goto | 0 | 1 | 26 | Noop | 0 | 0 | – 2009-07-26 01:35:50

+0

argh, здесь он отлично отформатирован http://dpaste.com/71454/ – 2009-07-26 01:36:21

+0

Привет, Пол, как насчет вставки его в исходное сообщение (или, конечно, ответ) с 4 заглавными записями каждый (это специально для кодирования). Таким образом, это не истечет. – Juergen

1

Я сделал этот класс синглтон (так называемого SQLAdapter), и это содержит два метода здесь, один, чтобы скопировать базу данных, если ее необходимо, а другой EXEC моего кода SQL:

Вот метод SQL-код, это был первый раз, когда я закодирован в Obj-C, так что просто игнорировать строки Append методы, я меняю это, как мы говорим ...

- (NSString *)getMapping:(NSString *)test{ 
    //Our return string 
    NSString *res = test; 

    // Setup the database object 
    sqlite3 *database; 

    NSString *sqlStmnt; 
    if (direction) sqlStmnt = @"select * from table where col1 = '"; 
    else sqlStmnt = @"select * from table where col2 = '"; 

    NSString *tStmt = [sqlStmnt stringByAppendingString:test]; 
    NSString *sqlState = [tStmt stringByAppendingString:@"'"]; 
    const char * sqlStatement = [sqlState UTF8String]; 

    // Open the database from the users filessytem 
    if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) { 
     // Setup the SQL Statement and compile it for faster access 
     sqlite3_stmt *compiledStatement; 
     //execute the statement 
     if (sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) != SQLITE_OK) { 
      NSAssert1(0, @"Error: during prepare '%s'.", sqlite3_errmsg(database)); 
     } 
     //bind our translation into the sql select statment 
     sqlite3_bind_text(compiledStatement, 1 , [word UTF8String], -1, SQLITE_TRANSIENT); 
     if(sqlite3_step(compiledStatement) == SQLITE_ROW) { //if execution is successful i.e. we get a match 
      //lets return the desired language translation 
      res = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, (direction) ? 2 : 1)]; 
     } 
     sqlite3_finalize(compiledStatement); //Release the compiled statement from memory 
    } 
    sqlite3_close(database); //lets return the translation 
    return res; 
} 

почти точно так же, как проект SQLiteBooks делает это, если я не ошибаюсь ...

+0

Бла, который испортил форматирование, здесь он красиво отформатирован: http://dpaste.com/71397/ – 2009-07-25 22:11:36

+0

Поэтому я переместил код, который открывает базу данных каждый раз, когда я хочу выполнить запрос, чтобы открыть базу данных когда программа загружается первым, я просто выполняю запросы. Узкое место, похоже, связано с sqlte3_step (stmt). Это определенно занимает самое длинное из всего. – 2009-07-26 05:16:14

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