在sqlite中一次两个查询的结果?

时间:2010-04-23 08:53:48

标签: c++ sql c optimization sqlite

我目前正在尝试优化从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);

(用于显示“m的第n页”)

我想知道,如果我可以连接这两个查询,并在一个sqlite3_exec()中询问它们,只需连接查询字符串即可。那么我的回调函数应该如何呢?我可以通过argc区分不同类型的数据吗?

您会建议哪些其他优化措施?

3 个答案:

答案 0 :(得分:2)

您可以使计数查询返回与选择查询相同的列数,并生成计数查询和选择查询的UNION

结果集的第一行将包含总计数。

另一个可能的解决方案在sqlite-users maillist的the post about SQL_CALC_FOUND_ROWS中描述。

关于您的选择查询的一个小注意事项:如果您使用datetime('now')将记录插入日志表,并且id是表的自动递增主键,则不需要按时间排序它足以按id DESC排序。由于自动递增的主键字段是ROWID的别名,因此您将获得显着的性能提升。

顺便说一下,time是SQLLite中的内置函数,因此您应该使用back-ticks(`)引用列名。

答案 1 :(得分:1)

您可以使用sqlite3_get_table功能查询来收集行 并获取结果行数。

答案 2 :(得分:1)

您可以使用triggers在单独的表中保留每个级别的条目数。插入条目时,触发器需要递增计数,并在删除条目时递减计数。

示例:

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);

然后,您不需要对每个显示页面进行计数(*)查询。