2013-08-06 51 views
1

我有一段軟件需要一個數據庫,並根據用戶的需求(主要是查詢表格SELECT AVG(<input1>) AS x, AVG(<intput2>) as y FROM <input3> WHERE <key> IN (<vals..> AND ...)生成圖表。這很好地工作。什麼時候包含一個索引(自動啓發式)

我有一個傳遞的文件(通常是大)數一個簡單的腳本,每個描述行

name=foo 
x=12 
y=23.4 
....... etc....... 

腳本經過的每個文件,保存變量名,和INSERT查詢各。然後,它加載變量名稱sort | uniq的變量名稱,並在它們之外生成CREATE TABLE語句(sqlite,有趣的是,即使它們實際上最終包含文本數據,所有列都是NUMERIC也行)。一旦完成,它會執行INSERTS(在單個事務中,否則需要很長時間)。

爲了提高性能,我在每行添加了一個基本索引。但是,這會大大增加數據庫的大小,並且只能提供適度的改進。

數據有三種基本類型:

  1. 單個值,其指示之類的東西程序版本等
  2. 幾個值(< 10),表明的是,象輸入參數
  3. 許多值(> 1000),主要是輸出數據。

第一種顯然不應該需要一個索引,因爲它永遠不會被排序。 第二種類型應該有一個索引,因爲它通常會被過濾。 第三種類型可能不需要索引,因爲它將用於輸出。 在將數據放入數據庫之前確定某個特定值的類型是令人討厭的,但這是可能的。

我的問題是雙重的:

  1. 有一些隱性的成本無關的指標,超出了我所見過的尺寸增加?
  2. 有沒有更好的方法來索引表格WHERE foo IN (5) AND bar IN (12,14,15)的過濾查詢?請注意,我不知道用戶會選擇哪一列,除此之外它將是一個類型2列。

回答

1

閱讀相關文件: Query Planning; Query Optimizer Overview; EXPLAIN QUERY PLAN

優化查詢的最重要的事情是避免I/O,因此不應對具有少於10行的表進行索引,因爲無論如何,所有數據都可以放入單個頁面,因此擁有索引只會強制SQLite讀取另一個索引頁面。

當您在大表中查找記錄時,索引非常重要。

  1. 無關索引使表更新變慢,因爲每個索引也需要更新。

  2. SQLite最多可以在查詢中爲每個表使用一個索引。 通過在兩列foobar上有單個索引,可以最佳地優化此特定查詢。 但是,爲查找列的所有可能組合創建此類索引很可能不值得。 如果查詢是動態生成的,最好的想法可能是爲每列有很好的選擇性創建一個索引,並依靠SQLite選擇最好的一個。

而且不要忘記運行ANALYZE

+0

我在找什麼。作爲一個方面說明,如果你想知道需要多少個索引來覆蓋n列的任何子集,在sqlite規則下(多列索引在左邊使用,所以'foo,bar'可以從' foo,bar,baz'索引,但不是'foo,baz,bar'索引),它對於偶數n結束爲n!/((n/2)!)^ 2,並且n!/(((n -1)/ 2)!((n + 1)/ 2)!)。也就是1,2,3,6,10,20,35,70,126,252 ......這對於5-6列(分別是10和20個指數)來說確實是非常合理的。 – zebediah49

相關問題