代码之家  ›  专栏  ›  技术社区  ›  SF.

在sqlite中同时执行两个查询的结果?

  •  3
  • SF.  · 技术社区  · 15 年前

    我目前正在尝试优化从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 回复  |  直到 15 年前
        1
  •  2
  •   newtover    15 年前

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

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

    另一种可能的解决方案在 the post about SQL_CALC_FOUND_ROWS 来自sqlite用户邮件列表。

    还有一个关于选择查询的小提示:如果将记录插入到 datetime('now') id 是表的自动递增主键,则不需要按时间排序,只需按 id DESC . 由于自动递增主键字段是rowid的别名,因此您将获得显著的性能改进。

    顺便说一句, time 是sqllite中的内置函数,因此应该用反勾号(`)引用列名。

        2
  •  1
  •   Nick Dandoulakis    15 年前

    您可以将查询与 sqlite3_get_table 函数来收集行
    并获取结果行数。

        3
  •  1
  •   Doug Currie    15 年前

    你可以使用 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);
    

    那么您就不需要对显示的每一页都使用count(*)查询了。