2011-01-06 8 views
1

Informixデータベースに500万以上のレコードを持つテーブルがあります。Informix DBのインデックス(インデックス?)の使用

これは実際のテーブルではありませんが、私が抱えている問題が表示されます。私はクエリを実行した場合IDX1(sale_id)、IDX2(sale_confirmed)、IDX3(VENDOR_ID)、idx4(purchaser_id)

表:販売
列:sale_id、sale_confirmed、VENDOR_IDは、
インデックスをpurchaser_id

select * 
from sales 
where sale_confirmed IS NULL 
or sale_confirmed = '' 

クエリは約4または5秒で完了します。

私はこのようなクエリを行う場合は、次の

select * 
from sales 
where vendor_id = 12345 
or purchaser_id = 12345 

を、クエリが約4または5秒で完了するまで実行されます。私はこのクエリ(2つの以前のクエリの組み合わせ)を実行した場合

しかし、私はそれをキャンセルする前に

select * 
from sales 
where (sale_confirmed IS NULL 
     or sale_confirmed = '') 
and (vendor_id = 12345 
     or purchaser_id = 12345) 

は、クエリは、15分間走りました。

データベースは、異なるインデックスを縦列に使用するほどスマートではないようです。つまり、idx2を使用してX個の行を見つけたり、そのX個の行内でidx3とidx4を使用することはできないようです - そうです、これを行うには十分にスマートであると思ったでしょうか?

WHERE句の2番目の部分を処理するときにidx3とidx4を使用するようにデータベースを強制する方法はありますか?

新しいインデックスを作成する以外の解決策はありますか?

ありがとうございました。

+0

どのバージョンのIDSを使用していますか?あなたの統計は十分に最新ですか?あなたはSET EXPLAIN ONでクエリプランを見ましたか? –

答えて

2

のみ2つの指標は、各部分にから選択する必要がUNIONとそれを試してみてください。

select * 
from sales 
where (sale_confirmed IS NULL 
     or sale_confirmed = '') 
and vendor_id = 12345 


UNION 

select * 
from sales 
where (sale_confirmed IS NULL 
     or sale_confirmed = '') 
and purchaser_id = 12345 

およびInformixは、インライン・ビューをサポートしている場合は、それとはベンダー/購入し、その後に基づいて行のセットを取得未確認の販売を除外する設定。

select inlineview.* from 
(
select * from sales 
where vendor_id = 12345 or purchaser_id = 12345 
) as inlineview 
where (sale_confirmed IS NULL or sale_confirmed = '') 

最後に、低カーディナリティ索引をsale_confirmedにドロップしたいと思うかもしれません。

P.S.私は通常、空の文字列、NULL、および他の値を許可するデータベース内の列を持っていません。私はあなたがそれを持っている場合、おそらくBITタイプにフィールドを制約するでしょう、1と0、0デフォルトで。

+0

+1 UNIONを使用しています。 –

1

'sale_confirmed'のカーディナリティが低いと思われるため、 'sale_confirmed'のインデックスは有用ではありません(NULL、はい、いいえ?)。より良いスキーマ設計は、 'sale_confirmed'にNOT NULLを強制し、CHECK制約は 'Y'または 'N'を強制し、特に指定しない限り、デフォルトで 'N'を与える​​ことができます。そうすれば、「売り上げ確認」のOR操作をやらなければならなくなります。これは面倒です。

Timで提案されているUNIONのテクニックは、まともな回避策になる可能性があります。

関連する問題