• 締切済み

目的のインデックスが使用されない・・。

以下のSQLではインデックス1を使用してほしいのですがインデックス2が使われています。 インデックス1を使用されるように変更する方法を 教えてください。 インデックス1:「NO_UKE」「CD_STS」 インデックス2:「CD_STS」 select CD_STS from T_STS where NO_UKE = 10 and CD_STS = 7

  • Oracle
  • 回答数1
  • ありがとう数1

みんなの回答

  • pjunk
  • ベストアンサー率32% (10/31)
回答No.1

Oracleならヒントでインデックスを指定できます。

参考URL:
http://www.atmarkit.co.jp/fdb/rensai/oraobstacle04/oraobstacle04_3.html
toshi_200578
質問者

お礼

参考にさせて頂きます。 ありがとうございました。

関連するQ&A

  • パフォーマンスについて

    現在1つのSQLで10秒程度かかります。 データが700万件あるのでそれが原因というのもありますが、それにしても遅いです。 以下のSQLです。 select CD_STS from T_STS where NO_UKE = '20000' and CD_STS = '07' インデックスに「NO_UKE」と「CD_STS」で作成しています。 なにかいい方法はありませんか?

  • パフォーマンスについて

    次の2つのSQLで10秒前後の開きがあります。 原因は「CD_STS」なのですが、理由がわかりません。 データは700万件あります。 インデックスは「NO_UKE」と「CD_STS」につけています。インデックスは全部で5つあります。 なぜこれほど違いがでるのでしょうか? 原因がわかったのでお客さんに説明したいのですが理由がわからなくて困っています。。 考えられそうな理由があればお願いいたします。 ■即■ select CD_STS from T_STS where CD_KAIIN = 50 and FL_DEL = 0 and NO_UKE = 10 and (CD_STS <= 7 and CD_STS >= 7) ■10秒前後かかる■ select CD_STS from T_STS where CD_KAIIN = 50 and FL_DEL = 0 and NO_UKE = 10 and CD_STS = 7

  • 性能の改善について

    以下の(1)のSQLと(2)のSQLで性能が全然違います。原因は明示的に「1」を取得するようにしているからなのですが、改善する方法はないでしょうか? (1)SQL(遅い) SELECT 1, /*+ INDEX(T_UKERUI T_UKERUIP1) */ T.NO_UKE FROM T_UKE T ,M_OFF O ,M_KAI K WHERE T.CD_OFR = O.CD_OFR AND T.CD_KAIIN = K.CD_KAIIN AND T.CD_STS IN (3, 4) AND T.CD_SHIP = 0001 AND T.NO_ADDNO = 0 (1)SQL(速い) SELECT /*+ INDEX(T_UKERUI T_UKERUIP1) */ T.NO_UKE FROM T_UKE T ,M_OFF O ,M_KAI K WHERE T.CD_OFR = O.CD_OFR AND T.CD_KAIIN = K.CD_KAIIN AND T.CD_STS IN (3, 4) AND T.CD_SHIP = 0001 AND T.NO_ADDNO = 0

  • sedに関する質問

    ★以下のファイルがあるとします。 SQL> select count(*) from koumoku where no = 1052 and mid =2; COUNT(*) ---------- 7 SQL> select count(*) from koumoku where no = 1053 and mid =3; COUNT(*) ---------- 4 SQL> select count(*) from setumei where no = 1054 and mid =2; COUNT(*) ---------- 9 SQL> select count(*) from setumei where no = 1055 and mid =7; COUNT(*) ---------- 5 SQL> select count(*) from imi where no = 1056 and mid =2; COUNT(*) ---------- 9 SQL> select count(*) from imi where no = 1057 and mid =6; COUNT(*) ---------- 3 ★ここでsedコマンドを利用して、 koumoku COUNT(*) ---------- 7 koumoku COUNT(*) ---------- 4 setumei COUNT(*) ---------- 9 setumei COUNT(*) ---------- 5 imi COUNT(*) ---------- 9 imi COUNT(*) ---------- 3 のように取り出したいのですが、方法が分からないので、 誰か教えてもらえますか?宜しくお願いします。

  • DATE型カラムのインデックスが効かない

    Oracle初心者です。 以下のような2種類のSQLをSQLPLUSで実行し、 実行計画を取得しました。 end_timeでfilterをかける際に、"TABLE ACCESS FULL"となっており、貼っているインデックスが使われていないことがわかりました。 #これがSQLの遅い主要因と考えています。。。。勘です。 インデックスが活用されていない原因としてはどのようなものが考えられるのでしょうか。 宜しくお願いいたします。 1) set autotrace traceonly select * from t_sample where end_time >= '2009-08-25' and end_time <= '2009-11-26' 2) set autotrace traceonly select * from t_sample where end_time >= to_date('2009-08-25', 'yyyy-mm-dd') and end_time <= to_date('2009-11-26', 'yyyy-mm-dd')

  • WITH句を使用したSQLの結果

    WITH句を使用して総件数と1~20件までのデータを同時に取得するSQLを組んでみたところ、 WITH TMP AS (SELECT ROW_NUMBER() OVER (ORDER BY NO) AS CHECKROWNUM,NAME FROM TEST_TBL ORDER BY NO) SELECT T1.ALLCNT, T2.* FROM (SELECT COUNT(*) ALLCNT FROM TMP) T1, TMP T2 WHERE T2.CHECKROWNUM BETWEEN 1 AND 20; Oracle10.2.0.3.0のバージョンで ALLCNTが21になってしまう現象が発生してしまいました。 Oracle10.2.0.4.0や9iでは発生せず正しい総件数が取得できるのですが、 バージョンによる不具合は考えられますでしょうか。 それともSQL自体なにか悪い部分があるのでしょうか。 ちなみに T2.CHECKROWNUM BETWEEN 1 AND 100; と帰るとALLCNTが101と帰ってきます。 また、WITH句を使わず下記のようにTMPの部分をWITH句で使用したSQLに 置き換えると正しくALLCNTが取れます。 SELECT T1.ALLCNT, T2.* FROM (SELECT COUNT(*) ALLCNT FROM (SELECT ROW_NUMBER() OVER (ORDER BY NO) AS CHECKROWNUM,NAME FROM TEST_TBL ORDER BY NO)) T1, (SELECT ROW_NUMBER() OVER (ORDER BY NO) AS CHECKROWNUM,NAME FROM TEST_TBL ORDER BY NO) T2 WHERE T2.CHECKROWNUM BETWEEN 1 AND 20;

  • PL/SQLでログを確認したい。

    以下のPL/SQLで取ってきた値をログか何かで確認したいのですが、いい方法がありますか? 想像では5行目あたりにログはきだす記述をするのかなと思うのですが、方法がわかりません。 どなたか教えてください。 -------------------------------------------- 1select count(*) into vn_CNT from t_ukerui 2 where no_toi = :new.no_toi 3 and no_uke = :new.no_kyaku 4 and no_gyo = 1; 5 6if ( vn_CNT > 0 ) then 7 --------------------------------------------

  • ORACLEのインデックスについて

    現在、ORACLE9を使用しているのですが INDEXについて理解できないことがあったので 教えてください。 組織、社員という2つしか項目を持たない 従業員という表があり600件ほどのデータがあります。 変更前は、 ・組織、社員にユニークインデックスは作成されていた。 ・600件ほどのデータの組織は全て同一。 となっており、その状態で select * from 従業員 where 組織 = 'ALL' and 社員 = '001' を流すとFULL SCANになっていました。 FULL SCANを回避できないかと思い、社員のみのインデックスを 追加し(* 一番下にインデックス追加時のSQLをはっています)  select * from 従業員 where 組織 = 'ALL' and 社員 = '001' を流すと追加したインデックスを読んでいました。 既に作成されていたユニークインデックスと異なるインデックスが 追加されたのかと思い、DBA_INDEXESの中を確認しましたが 異なっているのは、 ・UNIQUENESS ・INITIAL_EXTENT(ユニークインデックスは24576、  追加したインデックスは40960) ・LEAF_BLOCKS(ユニークインデックスは3、  追加したインデックスは2) の3点のみでした。 なぜこのような動きになるか理解できず、今後の対応に 迷っています。 ・原因 ・調査したらいい場所 ・参考資料 などがありましたら教えてください。 よろしくお願いします。 (*) インデックス追加時のSQL文は、create index 従業員A on 従業員 (社員) tablespace index storage (initial 40000 next 100000 maxextents unlimited pctincrease 0) pctfree 10となっています。

  • sqlのwhereで指定した条件の前後を取得したい

    テーブル=T) KEY DATA 001 あ 002 い 003 う 004 え 005 お SQL) SELECT DATA FROM T WHERE KEY = 003 ; 上記のSQLでは、「う」のデータしか取得できませんが、 「003」の前後1件、合計3件の「い」「う」「え」を取得する方法を教えて下さい。 ちなみに、 SELECT DATA FROM T WHERE KEY >= 003 AND ROWNUM <= 2 と SELECT * FROM ( SELECT DATA FROM T WHERE KEY < 003 ORDER BY KEY DESC ) WHERE ROWNUM < 1 のUNIONでは上手く行きませんでした。 よろしくお願いします。

  • 前方一致で索引(インデックス)が使用されない?

    社員表に対して、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の値によって   データ取得可否を判定するロジックが増えるのでちょっと。 これらの解決策に対するご意見、また、他に案がありましたら よろしくお願いします。