社員表に対して、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で質問しましょう!
似たような質問が見つかりました
- Access(アクセス) アクセス where句を使用して複数条件抽出をするには 2 2022/08/29 13:24
- MySQL 書籍の内容はまともでしょうか? 1 2023/01/22 03:07
- Excel(エクセル) PHPプログラムをエクセルに張り付けると検索ボックスがでてくる! 3 2022/05/08 07:10
- Visual Basic(VBA) VBAチェックボックスで有効無効切り替えできるように 5 2022/10/21 16:13
- MySQL PhpMyAdminで作成して実行せよ。 東京23区を、皇居を中心とした4つのエリア(南東, 南西, 1 2023/06/11 11:58
- SQL Server [SQLServer] テーブル名からカラム名を取得する 1 2022/08/23 21:20
- Oracle 質問です。 下記のテーブルとデータがあり、 取得想定結果のように出力したいです。 下記のsqlだと0 2 2023/05/23 19:10
- PostgreSQL DBFluteについて質問です。 環境:PostgreSQL java8 前提:webアプリケーショ 1 2022/07/07 00:49
- Oracle 下記のsqlで取得されるレコード以外を取得する方法ありますでしょうか。 SELECT B.番号, B 2 2022/04/20 23:21
- Excel(エクセル) excelの列幅高さが勝手に変わる(特定のPCだけ) 8 2022/07/14 16:51
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
キャッシュを使わずにSELECTを...
-
DATE型カラムのインデックスが...
-
likeとsubstrの使いわけについて
-
WHERE句の実行順序
-
WHERE句はJOIN結合前結合後どち...
-
Accessのマクロでモジュールを...
-
エクセルVBAでUserFormを起動し...
-
Access VBAで行ラベルが定義さ...
-
会社の〇〇部と〇〇課の違いっ...
-
エクセル 日付による並べ替え...
-
SQLサーバで和暦から西暦に変換...
-
SQLで部分的にGROUP BYしたいとき
-
百の位での四捨五入について
-
SQLserver算術オーバーフロ...
-
wordの差し込み印刷での日付表示
-
sqlplusのspoolで空白行出現
-
Accessの数値から時間に変換す...
-
全角空白のTRIMができない...
-
SQLite3のtext→date変換について
-
Statement ignored というエラー
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
キャッシュを使わずにSELECTを...
-
likeとsubstrの使いわけについて
-
WHERE句の実行順序
-
Like文の速度について教えてく...
-
WHERE句はJOIN結合前結合後どち...
-
ヒント句が無効になります
-
JOINの時のONとWHEREの違いにつ...
-
あいまい検索のパフォーマンス...
-
アナライズでほとんどの処理が...
-
SQL ORDER BYにおける条件について
-
800万件のテーブル読み込み...
-
問題解決のストーリーにて PDCA...
-
実行計画HASH JOIN RIGHT OUTER
-
oracleのanalyzeと処理時間につ...
-
PDCAを回すって?
-
【チューニング】インデックス...
-
Oracleで検索すると、フリーズ...
-
Oracle 実行計画、統計情報の見方
-
OEMで負荷の少ないSQLの実行計...
-
データ抽出の速度について
おすすめ情報