2016-07-04 51 views
0

這裏的sqlfiddle of my example,但讓我解釋一下:爲什麼SQLite在WHERE子句中使用文字列值時不使用索引?

當我有一個簡單的表是這樣的:

CREATE TABLE ForgeRock 
    (`id` int, `productName` varchar(7), `description` varchar(55)) 
; 

而且在productName列這樣一個簡單的指標:

CREATE INDEX test_idx ON ForgeRock(productName); 

我可以使用WHERE子句中的productName輕鬆選擇數據,並且正在使用我的索引。尼斯。

當我一個硬編碼值添加到我選擇,它也運作良好,並使用該索引中的列清單,太:

SELECT 
    0 as foo, 
    0 as bar, 
    productName, 
    description 
FROM 
    ForgeRock 
WHERE (foo = 0 AND productName IN ('OpenIDM', 'OpenDJ')) 

即使使用硬編碼foo列WHERE子句仍然使用索引(因爲它應該)。但是,這裏是我的問題:爲什麼在我將OR (foo = 1 AND bar IN (1))添加到WHERE子句時不使用索引?

SELECT 
    0 as foo, 
    0 as bar, 
    productName, 
    description 
FROM 
    ForgeRock 
WHERE (foo = 0 AND productName IN ('OpenIDM', 'OpenDJ')) OR (foo = 1 AND bar IN (1)); 

任何幫助,將不勝感激。再次,here's the sqlfiddle

回答

0

documentation說:

WHERE由連接或代替,並且可以處理條款約束[...]
對於任何給定的查詢,這裏所描述的OR子句優化的事實可以使用並不能保證它會被使用。 SQLite使用基於成本的查詢計劃器來估計各種競爭查詢計劃的CPU和磁盤I/O成本,並選擇它認爲最快的計劃。如果WHERE子句中有許多OR術語,或者單個OR-子句子項的某些索引不是非常有選擇性的,那麼SQLite可能會決定使用不同的查詢算法甚至全表掃描更快。

相關問題