2013-10-29 26 views
1

我在SQLLite的三列中設置了唯一索引,並且想知道是否需要其他索引,因爲從以下查詢中檢索結果有時需要將近10秒(數據庫大小僅爲25,000行):SQLLite中除了這個之外,還需要另外一個索引嗎?

SELECT * FROM books 
WHERE (Author="Roger Davies" COLLATE NOCASE AND 
Title>="My Best Days" COLLATE NOCASE AND 
CatID>"rtYY91" COLLATE NOCASE) 

OR Author > "Roger Davies" COLLATE NOCASE 

ORDER BY Author COLLATE NOCASE ASC, 
Title COLLATE NOCASE ASC, 
CatID COLLATE NOCASE ASC LIMIT 10 

的指標爲: CREATE UNIQUE INDEX ON booksIndex書(CATID,作者,標題)

感謝您的指導。

回答

2

該索引根本沒有使用。 (您可能已注意到這與EXPLAIN QUERY PLAN。)

若要使此查詢使用該索引,請將COLLATE NOCASE添加到index definition中的列。但是,索引中的列只能從最左邊的索引列開始使用,並且不等式比較(如> =)只能在一個列中使用(如果有索引並且阻止任何其他索引列從被使用。

因此,可以通過這個特定的索引來優化可能的比較是:

  • CatID = x;或
  • CatID > x;或
  • CatID = x AND Author = y;或
  • CatID = x AND Author > y;或
  • CatID = x AND Author = y AND Title = z;或
  • CatID = x AND Author = y AND Title > z

(但是,優化能重新排序比較,在WHERE子句中匹配這一點)。

如果你想優化由筆者首先排序的查詢,你需要一個索引作爲第一列。

如果您可以使用不同的排序順序進行不同的查詢,則需要多個索引。 在這種情況下,只有一列索引可能是一個更好的主意,這樣索引的數量就不會失控。

+0

謝謝CL。因此,只需在每一列上設置一個可能被搜索的索引,對吧?如果我在已有該索引的列上運行CREATE INDEX,SQLLIte會優雅地忽略它嗎?我需要改進索引到用戶的數據庫。另外,我需要保留原始索引,以便三列保持唯一性,但我也可能會爲它們設置單個索引。如果是這樣的話,是否有必要讓COLLATE NOCASE原始的唯一索引,或只是在索引上做到這一點? – Shaun

+0

SQLite不會阻止您創建重複的索引。如果您想防止不區分大小寫的重複項,您需要在原始唯一索引上使用COLLATE NOCASE。 –

+0

可以將COLLATE NOCASE改造爲現有索引,還是最好放棄並重新創建索引?最後一個問題(謝謝CL) - 將索引應用於已填充數據的列時,索引是否包含已存在的內容,或者是否需要告訴SQLLite刷新? – Shaun

相關問題