![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67b6d)
社員表に対して、SQLを実行します。
(社員名)は任意の文字列です。
select syainNO
from syain
where deleteflg = '0'
and syain_kubun = '2'
and syain_mei like '(社員名)%';
索引は以下の2つです。
// deleteフラグに対する索引・・・(a)
create index syain_index_1 on syain (
deleteflg
)
// 社員区分と社員名に対する索引・・・(b)
create index syain_index_2 on syain (
syain_kubun,
syain_mei
)
deleteflgは0と1しか存在せず、0がほとんどです。
syain_kubunは1と2のみで、1が9割、2が1割程度です。
このとき、SQL実行時にトレースを分析すると、
(a)が使用され、(b)は使用されていません。
deleteflgとsyain_kubunのデータ分布からすると、deleteflg = '0'の条件により、
明らかに(b)の方が絞り込みを行えると思うのですが、使用されないのはなぜでしょうか?
where syain_kubun = '2'
and syain_mei like '(社員名%) '
and deleteflg = '0';
のように、条件の順番を入れ替えても効果はありませんでした。
試しにwhere句を変えてみると、(b)の索引が使用されます。
(likeをやめ、=を指定)
where deleteflg = '0'
and syain_kubun = '2'
and syain_mei = '(社員名) ';
この2つの違いは何でしょうか?
解決策として、以下を考えています。
(a)の索引は事情があって削除はできません。
(i)deleteflg = '0' を deleteflg != '1' にする
→(a)の索引が有効にならないようにする。
ただし、パフォーマンスに影響がないか
(ii)deleteflg = '0' を条件から外す
→SQLを組み立てるjava側で、deleteflgの値によって
データ取得可否を判定するロジックが増えるのでちょっと。
これらの解決策に対するご意見、また、他に案がありましたら
よろしくお願いします。
A 回答 (2件)
- 最新から表示
- 回答順に表示
No.2
- 回答日時:
3つほど。
1つは
b索引のカラム順序が悪いような気がします。
bの索引を使うとなるとまず1割程度までしか
絞込みを行えない社員区分での絞込みを行う必要があり、その分あまり効率のよい索引とはOracleはみなしません(その後の社員名で非常に少ない数まで絞り込めると分かっていても1つ目の絞込みが効率が悪ければOracleは候補からはずすことも十分に考えます。)
ですのでb索引のカラム順序を逆にして社員名から
絞込みを行わすようにすればOracleが選んでくれる確立が高くなります。
社員区分は1割程度の絞込みしか行わないということで
あまりOracleがこの索引を能動的に使うとは思えません。Oracleにといって1割もヒットするということは索引ではなく、全表走査の方が速いと決断することが多いです。
つぎにanalyzeをしっかりしてやるということです。
analyzeによってその表の中に何件のレコードがあって各カラムのデータ分布がどうなっているのかをしっかり把握できるのでより最適な実行計画をOracleが立てることができます。
最後に社員区分はNUMBER型ではないですよね?
SQL文を見ると''で囲っているのでおそらくCHARか
VARCHAR型だとおもうのですがここがずれていると
またインデックスを使う可能性がなくなってきます。
No.1
- 回答日時:
バージョンもオプティマイザも不明なので、回答しにくいのですが・・
どの索引を使うか、はたまた索引を一切使わないか、などの判断は、
最終的にオプティマイザの決めることなので、オプティマイザが
お望みの索引検索を行うと判断しやすいように方向付けすることしか
出来ません。
今回の場合、RBOでもCBOでも、オプティマイザヒントで索引を指定した方が
良い結果になるような気がします。(前置きのように確実な解決ではないけど)
select /*+ INDEX(syain syain_index_2) */ syainNO
from syain
where deleteflg = '0'
and syain_kubun = '2'
and syain_mei like '(社員名)%';
としてみた場合、どうなりますか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・「I love you」 をかっこよく翻訳してみてください
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・昔のあなたへのアドバイス
- ・かっこよく答えてください!!
- ・あなたが好きな本屋さんを教えてください
- ・スタッフと宿泊客が全員斜め上を行くホテルのレビュー
- ・【大喜利】【投稿~8/27】 こんなガソリンスタンド二度と来るか!なぜそう思った?
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・【お題】動物のキャッチフレーズ
- ・【お題】甲子園での思い出の残し方
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・「それ、メッセージ花火でわざわざ伝えること?」
- ・自分用のお土産
- ・人生で一番お金がなかったとき
- ・一番好きなみそ汁の具材は?
- ・泣きながら食べたご飯の思い出
- ・ちょっと先の未来クイズ第1問
- ・ゴリラ向け動画サイト「ウホウホ動画」にありがちなこと
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
キャッシュを使わずにSELECTを...
-
WHERE句の実行順序
-
likeとsubstrの使いわけについて
-
実行計画HASH JOIN RIGHT OUTER
-
Access VBAで行ラベルが定義さ...
-
エクセルVBAでUserFormを起動し...
-
Statement ignored というエラー
-
ODBCリンクの際にACCESSでは読...
-
【Excel VBA】 WorksheetやRa...
-
エクセル 日付による並べ替え...
-
Accessのマクロでモジュールを...
-
SQL文のエラー
-
SQL*Loader フォーマット変換...
-
全角空白のTRIMができない...
-
14桁の日付(YYYYMMDDHHMMSS)を...
-
sqlplusでヘッダーが付かない
-
VBA プロシージャの名前の取得
-
ストアドプロシジャからストア...
-
SQLサーバで和暦から西暦に変換...
-
excel/vba/public変数
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
キャッシュを使わずにSELECTを...
-
WHERE句の実行順序
-
likeとsubstrの使いわけについて
-
問題解決のストーリーにて PDCA...
-
ヒント句が無効になります
-
実行計画HASH JOIN RIGHT OUTER
-
SQL ORDER BYにおける条件について
-
Like文の速度について教えてく...
-
アナライズでほとんどの処理が...
-
あいまい検索のパフォーマンス...
-
ORACLEでwhere句の検索順序
-
JOINの時のONとWHEREの違いにつ...
-
oracleのanalyzeと処理時間につ...
-
WHERE句はJOIN結合前結合後どち...
-
PDCAを回すって?
-
【チューニング】インデックス...
-
計画段階での怠惰
-
DATE型カラムのインデックスが...
-
外部結合と等価結合のパフォー...
-
表の結合(性能)
おすすめ情報