2010-04-23 55 views
3

我目前正在試圖優化從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); 

(用於顯示「頁面n的m「)

我想知道,如果我可以連接兩個查詢,並要求他們在一個sqlite3_exec()簡單地連接查詢字符串。我的回調函數應該如何看待?我可以通過argc區分不同類型的數據嗎?

,你有什麼建議其他優化?

回答

2

您可以使計數查詢返回與選擇查詢相同的列數,並使計數查詢和選擇之一成爲UNION

結果集的第一行包含總計數即可。

另一種可能的解決方案是在從the post about SQL_CALC_FOUND_ROWS源碼用戶郵件列表說明。

以及您選擇查詢一個小提示:如果你插入記錄到日誌表datetime('now'),並id是表的自動遞增的主鍵,然後按時間排序不是必需的,這是不夠的id DESC排序。由於自動遞增的主鍵字段是一個別名ROWID,你會得到一個顯著的性能提升。

順便說一句,time是SQLLite中的一個內置函數,所以你應該用引號(`)引用列名。

+0

實際上,由於DST變化和時鐘調整,首先認爲按時間排序是必要的。然後它被認爲是適得其反的(將DST改變之前和之後的原木混合在一起)並且隨後被報廢。 – 2011-09-15 15:16:30

1

您可以使用您的查詢與sqlite3_get_table函數收集行
並獲取結果行數。

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

這樣你就不會需要一個COUNT(*)查詢顯示的每一頁。