2017-05-17 8 views
2

2つの一致する列(c1、c2)を持つ2つのテーブルがあります。OR演算子を持つ列の複合インデックス

TABLE_A TABLE_B 
======= ======= 
id   id 
c1   c1 
c2   c2 
double  col_y 
      col_z 

と私のクエリで私はレコードが似列ごとに一致しているかどうかを知っておく必要があります。今、私は列c1のための一つの指標と列c2に1つのインデックスを持っている

UPDATE table_a a SET double='Y' 
WHERE EXISTS (SELECT * 
       FROM table_b b 
       WHERE a.c1=b.c1 OR a.c2=b.c2); 

クエリを高速化するために、c1またはc2(c1とc2ではない)を検索するので、列c1とc2から複合インデックスを作成できますか?

答えて

1

このインデックスを作成することはできません。しかし、2つの別々のクエリにクエリを書き直す必要があります。

UPDATE table_a a SET double='Y' 
WHERE EXISTS (SELECT 1 
       FROM table_b b 
       WHERE a.c1=b.c1     
        union all 
       SELECT 1 
       FROM table_b b 
       WHERE a.c2=b.c2); 

はいあなたは複合インデックスを作成することができますor expansion

+0

OR演算子の間に句の順序はありますか?つまり、最初の場所に置く方がマッチが早いとc2がより早く見つかることができますか? – sbrbot

+0

これは場合によってはこれが役立つことがあります。しかし、データベースはクエリの変換を行い、最速の方法を見つける必要があります。 –

1

約「または拡張」良い記事があります..!

複合インデックスは、クエリが一般にインデックス内のすべての(またはほとんどの)カラムを使用する場合に最も便利です。また、取り出されるデータが索引内に含まれている場合にも、これらは便利です。例えば、以下のSELECTステートメントで:

SELECT c1, c2 
FROM sometable 
WHERE c1 = somevalue; 

あなたはc1c2上の個々のインデックスを持っていた場合、Oracleは必要なテーブルブロックに引き出すためにインデックスからレコードを使用し、その後c1のインデックスにアクセスします。 c2インデックスはまったく使用されませんでした。 c1c2に複合インデックスがある場合、オプティマイザはほぼ確実にインデックスをスキャンし、インデックスブロックを使用してデータを返します。これは決してテーブルには触れません。

複合インデックスの列が多いほど、スキャンするのが高価になります。その表に対する問合せが索引のほとんどまたはすべての列を日常的に使用しない場合、個々の列の対応する単一列索引よりも少なく使用される可能性があります。

+0

ここで強調は、列間のOR演算子(ANDではなく)です。 AND演算子があった場合、あなたが言ったことはすべてOKです。クエリ 'WHERE c1 = sth1 AND c2 = sth2'を実行すると複合インデックスが役立ちますが、ここでは' WHERE c1 = sth1 OR c2 = sth2' – sbrbot

関連する問題