Результаты двух запросов одновременно в sqlite? - PullRequest
3 голосов
/ 23 апреля 2010

В настоящее время я пытаюсь оптимизировать медленный процесс извлечения страницы записей журнала из базы данных SQLite.

Я заметил, что почти всегда извлекаю следующие записи вместе с количеством доступных записей:

        SELECT time, level, type, text FROM Logs
         WHERE level IN (%s)
         ORDER BY time DESC, id DESC
         LIMIT LOG_REQ_LINES OFFSET %d* LOG_REQ_LINES ;

вместе с общим количеством записей, которые могут соответствовать текущему запросу:

        SELECT count(*) FROM Logs WHERE level IN (%s);

(для отображения "страницы n из m")

Интересно, смогу ли я объединитьдва запроса, и задайте их оба в одном sqlite3_exec (), просто объединяя строку запроса.Как должна выглядеть моя функция обратного вызова?Могу ли я различить данные разных типов по argc?

Какие еще варианты оптимизации вы бы предложили?

Ответы [ 3 ]

2 голосов
/ 24 апреля 2010

Вы можете заставить запрос подсчета возвращать то же число столбцов, что и запрос выбора, и сделать UNION запроса подсчета и запроса выбора.

Первая строка набора результатов будет содержать общее количество.

Другое возможное решение описано в посте о SQL_CALC_FOUND_ROWS от sqlite-users maillist.

И небольшое замечание о вашем запросе выбора: если вы вставляете записи в таблицу журнала с помощью datetime('now'), а id - это автоматически увеличиваемый первичный ключ таблицы, то сортировка по времени не требуется, и этого достаточно для сортировать по id DESC. Поскольку поле первичного ключа с автоматическим приращением является псевдонимом ROWID, вы получите значительное улучшение производительности.

Кстати, time - это встроенная функция в SQLLite, поэтому вы должны заключать имя столбца в кавычки (`).

1 голос
/ 23 апреля 2010

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

Пример:

create table Log_counts (level primary key, count);

create trigger Log_insert_trigger after insert on Logs
  for each row
  begin
    update Log_counts set count = count + 1 where level = new.level;
  end;

create trigger Log_delete_trigger after delete on Logs
  for each row
  begin
    update Log_counts set count = count - 1 where level = old.level;
  end;

Вам необходимо инициализировать Log_counts срассчитывает на уровень;в пустой базе данных для каждого уровня ...

insert into Log_counts (level, count) values (%s, 0);

Тогда вам не понадобится запрос количества (*) для каждой страницы отображения.

1 голос
/ 23 апреля 2010

Вы можете использовать свой запрос с функцией sqlite3_get_table , чтобы собрать строки
и получить количество строк результата.

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