2014-04-02 49 views
0

我有以下查詢:
使用索引GROUP BY

SELECT * FROM messages GROUP BY peer 

(說實在的,與加入更復雜,但我忽略他們在這裏爲簡便起見)
的問題是,SQLite不使用任何索引並始終執行表的全面掃描。預計,它可以在小型數據集上快速運行,但在包含成千上萬行的大型表中速度很慢。以下是EXPLAIN QUERY PLAN命令的輸出結果:
0|0|0|SCAN TABLE messages USING INDEX messages_peer_mid (~1000000 rows)
儘管它顯示「USING INDEX」,它仍會執行全面掃描。有什麼辦法讓SQLite使用這個查詢的索引,或者放棄GROUP BY並尋找其他方法更好?

回答

0

該計劃考慮到數據量並執行掃描,因爲它的算法可能會得出結論,它會更快地完成掃描。

其他評論,你的查詢沒有WHERE條件,你正在返回所有列,所以你爲什麼不希望表掃描?

+0

我想他說他的查詢只是爲了簡單起見而寫的。 – DNac

+0

我只能評論我所知道的..對於所有我知道他的實際查詢沒有where子句或仍然(顯然)需要掃描 –

+0

同意這一個。 – DNac

0

索引幫助從表中選擇記錄(使用WHERE子句或作爲JOIN操作的結果)。 GROUP BY是在之後的一組記錄上執行的,它們已從表格中選擇並檢索到。它不能通過索引來協助。

如果您想了解更多關於索引在查詢中可用的選項,請發佈整個查詢。您還注意到,您提供的SQL是您正在運行的代碼的符號表示形式,但如果您真的在使用*或在您的語句中使用除peer以外的任何非聚合字段名稱,則可能不會得到你想要的結果。

最後,你問「最好放棄GROUP BY並尋找其他方法?」 GROUP BY用於SQL中的特定功能(從非聚合數據生成新的聚合結果集)。如果這是你的目標,GROUP BY可能是最好的解決方案(因爲它遵循數據庫引擎,高度優化並認識到數據庫統計數據是如何檢索和處理數據的決定)。如果這不是您的目標,並且您正在嘗試使用GROUP BY作爲其他功能的「方法」,請告訴我們您實際嘗試實現的目標。

+0

我使用此查詢從包含消息的表中獲取聊天列表。其實我只需要每次聊天的最後一條消息的ID(這是我的錯誤);然後我可以選擇具有子查詢的細節,因爲它使用索引,所以它會很快。通過「其他方法」,我的意思是像使用這些ID創建單獨的表格並使用觸發器更新它,例如。 – Grishka

+1

您是否在* all *聊天的最新消息之後,或者僅限於您在應用程序的任何給定屏幕上感興趣的聊天子集。如果您需要幫助優化,請編輯您的原始問題,使其至少具有完整的SQL(表結構也可能相關)。 –