2016-07-04 3 views
0

ここsqlfiddle of my exampleだが、私が説明しましょう:私はWHERE句でリテラルカラムの値を使用するときにSQLiteがインデックスを使用しないのはなぜですか?

CREATE INDEX test_idx ON ForgeRock(productName); 

私はこのような単純なテーブルを持っている場合:

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

そして、このようなproductName列に単純なインデックスWHERE句でproductNameを使用してデータを簡単に選択でき、インデックスが使用されています。ニース。

私も、私はそれもうまく機能し、インデックスが使用され、選択していた列のリストにハードコードされた値を追加

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

でもハードコーディングされたfoo列でを使用してWHERE節は引き続き索引を使用します(必要な場合)。しかし、ここに私の質問です:WHERE句にOR (foo = 1 AND bar IN (1))を追加すると、インデックスが使用されないのはなぜですか?

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の代わりにして処理することができますされている句の制約[...]任意のクエリに対して
、OR句の最適化は、ここで説明しているという事実それが使用されることを保証するものではありません。 SQLiteは、コストベースのクエリプランナを使用して、競合するさまざまなクエリプランのCPUおよびディスクのI/Oコストを予測し、最速と思われるプランを選択します。 WHERE句にOR項が多数ある場合や、個々のOR句サブタスクのインデックスの一部があまり選択的でない場合、SQLiteは別のクエリアルゴリズムやフルテーブルスキャンを使用する方が速いと判断することがあります。

関連する問題