2009-04-28 110 views
34

我有(例如)索引:多列索引是否也適用於單列選擇?

CREATE INDEX someIndex ON orders (customer, date); 

這是否僅索引加快地方客戶和日期使用或它加速查詢像這樣太單列查詢?

SELECT * FROM orders WHERE customer > 33; 

我正在使用SQLite。


如果答案是肯定的,爲什麼它可以爲每個表創建多個索引?


另一個問題:如何更快地被組合指數有兩個分隔符指標相比,當你在查詢中使用兩個列?

回答

32

marc_s對您的第一個問題有正確答案。多鍵索引中的第一個鍵可以像單個鍵索引一樣工作,但任何後續鍵都不會。

至於組合索引的速度取決於您的數據以及如何構建索引和查詢,但它通常很重要。索引基本上允許Sqlite在字段上進行二分搜索。

使用,如果你運行查詢,你給的例子:

SELECT * from orders where customer > 33 && date > 99 

sqlite的使用將在整個表二進制搜索首先獲得所有結果,其中客戶> 33.然後,它會做一個二進制搜索只那些結果查找日期> 99.

如果您對客戶和日期使用兩個單獨索引執行相同的查詢,Sqlite將不得不二進制搜索整個表兩次,第一次爲客戶,第二次爲日期。

因此,您將看到多少速度提升取決於您如何構建與查詢相關的索引。理想情況下,索引和查詢中的第一個字段應該是消除最可能的匹配的字段,因爲這會大大減少第二個搜索必須執行的工作量,從而實現最大的速度提升。

欲瞭解更多信息,請參閱本: http://www.sqlite.org/optoverview.html

+2

如果第一列是不等式表達式(例如customer> 33),SQLite將不使用索引的第二列。 (大多數數據庫引擎會很難)。 – vmatyi 2013-01-02 10:13:43

+1

如果您創建了兩個單獨的索引,則只會使用其中的一個,另一個表達式將在第一個生成的結果集上進行評估。 (在Oracle上,它可以執行兩個索引搜索並與結果集相交,如果優化是基於成本的並且某些標準滿足的話,但那是罕見的情況)。 – vmatyi 2013-01-02 10:16:48

5

我很肯定這會工作,是的 - 它確實在MS SQL Server中。

但是,如果您只需要選擇日期,則此索引不能幫助您。日期範圍。在這種情況下,您可能需要在日期上創建第二個索引以提高這些查詢的效率。

Marc

+0

謝謝,那就是我不確定的地方。在這種情況下,我將創建兩個單獨的索引。 – 2009-04-28 05:47:40

3

我通常使用綜合指標,通過數據整理我想分頁或請求「streamily」。

假設客戶可以進行多個訂單..並且客戶0到11存在,並且每個客戶都有幾個訂單都以隨機順序插入。我想根據客戶編號和日期排序查詢。您應該對id字段進行排序,最後進行拆分,以便客戶擁有多個相同日期(即使永遠不會發生這種情況)。

sqlite> CREATE INDEX customer_asc_date_asc_index_asc ON orders 
      (customer ASC, date ASC, id ASC); 

獲取第1頁排序的查詢(限10項):

sqlite> SELECT id, customer, date FROM orders 
      ORDER BY customer ASC, date ASC, id ASC LIMIT 10; 

2653|1|1303828585 
2520|1|1303828713 
2583|1|1303829785 
1828|1|1303830446 
1756|1|1303830540 
1761|1|1303831506 
2442|1|1303831705 
2523|1|1303833761 
2160|1|1303835195 
2645|1|1303837524 

獲取下一個頁面:

sqlite> SELECT id, customer, date FROM orders WHERE 
      (customer = 1 AND date = 1303837524 and id > 2645) OR 
      (customer = 1 AND date > 1303837524) OR 
      (customer > 1) 
      ORDER BY customer ASC, date ASC, id ASC LIMIT 10; 

2515|1|1303837914 
2370|1|1303839573 
1898|1|1303840317 
1546|1|1303842312 
1889|1|1303843243 
2439|1|1303843699 
2167|1|1303849376 
1544|1|1303850494 
2247|1|1303850869 
2108|1|1303853285 

等等......

使用索引時,可以減少服務器端索引掃描,否則將使用查詢OFFSET和LIMIT。查詢時間變長,偏移量越高,驅動器越難搜索。使用這種方法消除了這一點。

如果您計劃稍後加入數據,但每個請求僅需要一組有限的數據,則建議使用此方法。如上所述針對SUBSELECT進行連接以減少大型表的內存開銷。