SQL、Oracleでの文字列操作のパフォーマンス向上法

このQ&Aのポイント
  • Oracle7を使用して、文字列操作(連結、切り出し)のパフォーマンスを向上させる方法を教えてください。
  • 文字列連結(||)を使用せずに、外部結合付きでaテーブルのnum, code, seqを結合したものとbテーブルのbangoが同じかどうか検索するSQLのパフォーマンスを向上させる方法を教えてください。
  • 検索速度が遅くなるため、文字列連結(||)を使用せずにaのnum, code, seqとbのbangoを比較するSQLのパフォーマンスを向上させる方法を教えてください。
回答を見る
  • ベストアンサー

SQL、oracleにて文字列操作(連結、切りだし)のパフォーマンス向上法

oracle7を使用しています。 #desc a num  char(8) code char(2) seq char(2) ・・・ #desc b bango char(12) ・・・ 上記場合で aのnum,code,seq を結合したものと bのbangoが 同じかどうかの検索を外部結合付きで行いたいとします。 where bango(+) = num || code || seq で動作は正常に行われるのですが、検索速度がかなり重くなってしまいます。 文字列連結(||)は重くなるというのを聞いたことがあるのでできれば (||)を使用したくないのです。 where substr(bango,0,8) (+) = num and substr(bango,9,2) (+) = code and substr(bango,11,2) (+) = seq とすると外部結合のところでおこられちゃいました。 文字列連結をつかわずに上記SQLの検索パフォーマンス向上法を どなたか教えていただけませんか?

  • jyunk
  • お礼率43% (16/37)

質問者が選んだベストアンサー

  • ベストアンサー
noname#62349
noname#62349
回答No.2

再投稿です。CONCAT()関数は試してみましたか? ||演算子と同じです。 でも処理時間が早くなるか自信ないです。 うまくいかなかったらすみません。 where bango(+) = CONCAT(num, code, seq)

jyunk
質問者

補足

向上はあまりみられませんでした。 すいません。 経過: 00:00:46.30 -> 経過: 00:00:38.98 あとCONCATは二つのものしか比較できませんので 正しい書式は  concat(num, concat(code,seq ) ) だと思います。 ありがとうございます。

その他の回答 (4)

noname#62349
noname#62349
回答No.5

しつこくてすみません。 新規でbangoフィールドのINDEX追加したらどうでしょう。 テーブル定義の変更も不可なのかな?だとしたらつらい… num,code,seqに設定されてても結合してしまったら インデックス効果はありません。 あと記憶が定かじゃないんですが 条件の左側の項目にインデックスが付いてないと駄目だったような。。。 つまり前回の回答を例にすると INDEX(A, B)だった場合、 where char1 = A and char2 = B じゃ効かないということです。 うそだったらごめんなさーいい あまりお役に立てなくてすみません。 頑張ってください!!

jyunk
質問者

お礼

テーブルにindexをつけたりとtableに手を加えることは できないのです。すいません。 あと何度も回答ありがとうございました。 結果 where   substr(bango(+),1,8) = num  and substr(bango(+),9,2) = code  and substr(bango(+),11,2)= seq で速度の向上ができました。 ただ、場合によってはsubstrの方が||より遅くなるときも ありましたが、今回はsubstrでうまくいきました。 本当にありがとうござました。

noname#62349
noname#62349
回答No.4

再々投稿です。 検索ってことはselectで抽出するってことですか? select num || code || seq A from table where bango(+) = A ってな具合に別名をつけるのはどうでしょう。 これも自分では試してないんで速くなるかわからないんですけど。 where以降の条件文がゴテゴテしてると遅くなる気がして… あとyujiさんのおっしゃるとおり、インデックスが あるのとないのではかなりスピード違うと思います。 ただ条件の項目数とインデックスの項目数が一致していないと 意味が無いです。 where A = char1 and B = char2 という場合は、INDEX(A, B)じゃないと高速になりません。 以前速くて今は遅いっていうのはちょっとした 条件文の変更で起こってしまった可能性はないでしょうか。

jyunk
質問者

補足

selectで抽出ではありません。 目的は where句の書き方?の違いによる検索速度なんです。 ちなみに別名をつけてもあまり向上がみられませんでした。 使用しているoracleはコストベースで設計しており indexやwhere句の書き方の順番とはあまり関係なくoracleに 判断させています。 (それがそもそも原因といわれたらどうしようもないですが) 一応、indexの一番はじめの検索キー、主キーは num,code,seqに設定しております。  何回もすいません。ありがとうございます。 原因はおっしゃるとおりちょっとした条件文の違いだとは 思いますが、条件の内容は同じなので条件文の書き方の違いだと思ってます。 私が今回where句で使用したのは || なので それが速度低下につながっていると思った限りです。

  • yuji
  • ベストアンサー率37% (64/169)
回答No.3

どうしても高速に検索したいのであれば、 num || code || seq の結果を格納した列を元のテーブルに追加すればいいのでは? INSERT, UPDATE 時にこの値を更新するようなトリガーを 入れておけばいいでしょう。 ちなみに、 where substr(bango,1,8) (+) = num and substr(bango,9,2) (+) = code and substr(bango,11,2) (+) = seq のように substr を使うとbango列のインデックスを見なくなるので 余計に遅くなる可能性があります。 (もしかして、最初からbango列にインデックスがついていないとか?)

jyunk
質問者

補足

インデックスのことは考慮していませんでした。 文字列連結と、どちらがパフォーマンスがでないか 後学のために調べてみてもいいですね。 あと、このテーブルは変更できないのです。 すいません。 以前は5秒程度で検索できた、と言ってる方がいまして、 私の力量不足で非常に悩んでおります。 (現在は40秒程度、concat使用で38秒程度) ありがとうございました。

noname#62349
noname#62349
回答No.1

質問の回答ではないですがちょっと気になったことが… where substr(bango,1,8) (+) = num and substr(bango,9,2) (+) = code and substr(bango,11,2) (+) = seq が正しいのでは?

jyunk
質問者

補足

すいません。 substrの第二引数は n文字目 でしたね。 substr(bango,1,8) が正しいです。 お騒がせしました。

関連するQ&A

  • 文字の連結がうまくいかない

    CString SQL_st; CString SQL_and; CString SQL_end; CString SQL_update; SQL_st = "update mac3data set read_flg = 1 where (seq >= "; SQL_and = ") and (seq <= "; SQL_end = ")"; SQL_update = SQL_st + st_seq + SQL_and + en_seq + SQL_end; 上記のように連結して実行すると、SQL_update には、 update mac3data set read_flg = 1 where (seq >= 1.00 までしか入っていません。 SQL_and 以後の文字が連結できません。 どこに問題があるのでしょうか? st_seq には、1.00 en_seq には、89.00 が入っています。

  • 文字列の連結

    文字列の連結 select * from test where testcolum=変数名 といった感じで、文字列と変数を連結したいのですがやり方がわかりません。 declare cdata varchar2(20); begin cdata:='sample'; 'select * from test where testcolum=' || cdata; end; 上のように、select文を動的に変更して実行したいのです。 よろしくお願いします。 /

  • 文字列連結、文字列長について

    初心者ですみません。 VC++で文字列(CHAR)同士を連結の仕方と CSteingに入力文字がある場合その文字列長さは どの様にして求めるのでしょうか? お教えください。 具体的にお教えいただければ助かります。

  • 文字列連結を行いたい

    以下のようなテーブル「TABLE_A」があります。 何とかSQLで抽出結果のようにしたいのですが、 方法が思いつきません。 【TABLE_A】  CODE | HIDUKE  -----|------------  1 | 2005/06/01  1 | 2005/06/02  1 | 2005/06/03  2 | 2005/06/01  2 | 2005/06/03 【抽出結果】  CODE | rst  ---------------------------------------------  1  | 2005/06/01 2005/06/02 2005/06/03  2 | 2005/06/01 2005/06/03  (列「CODE」単位に列「HIDUKE」を文字列連結を行う) どなたかご教授ください。 よろしくお願いいたします。

  • 文字列の連結

    ポインタ変数で宣言された3つ以上の文字列を連結したいのです。 そこで char *str1 = "Hello,"; char *str2 = "Mr."; char *str3 = "Brown."; char msg[100]; strcat(msg,strcat(str1,strcat(str2,str3))); printf(msg); としたがやっぱり駄目でした。 strcat(str2,str3)からして駄目なんだとはなんとなくわかるのですが どうしたら解決できるのかわかりません。 結果的には printf(msg); ->Hello,Mr.Brown. としたいのです。解決案をご教授いただけないでしょうか。 お願いいたします。

  • C言語での文字の連結

    こんにちは。 C言語で困っているので、どなたかご教示お願いいたします。 char buff[16]に「東京」(JIS)という文字の16進表示の文字列が格納されており、 その先頭にJISコードの始まりである = 1B2442(0x1B2442) をつけたいのですが、 連結の仕方がわかりません。 最終的に使いたいのはJISコードの始まりが連結されたbuffです。 すみませんが、教えてください!

  • エクセル 文字列連結演算子で文字列を結合

    文字列連結演算子の「&」 を使って文字列を結合し、その間に()を投入したいです。 A列   B列  C列        D列 高橋太郎 東京  文字連結演算子  高橋太郎(東京) C列 =A1&(B1) ではエラーがでます。正しい書式を教えてください。 A列    B列  C列   D列  E列        F列 高橋太郎 (    東京   )  文字連結演算子   高橋太郎(東京) E列 =A1&B1&C1&D1 ってのは分かるのですが、もっとスッキリするものはないでしょうか? 宜しくお願いします。

  • Excel文字列の連結について教えてください(VBA)

    Excelの文字列の結合について教えてください。 色々調べたのですが、VBA自体がよくわからず困っています。 やりたい事は、(Excel表をご参考) 『セルA1とB1とA2の文字を固定で、セルA3以降の文字以降を  順次連結してcsvに書き出すVBAを作成したい。』 どうしても繰り返す連結マクロがわかりません。 ExcelVBAに詳しい方、教えてください。 よろしくお願いします。 結果例) 20080501A01 20080501A02 20080501B01 20080501C01   ・   ・(300件以上続きます) <Excel表>    A列  B列 1  2008  05 2  01    3  A01 4  A02 5  B01 6  C01 7  ・ 8  ・

  • 文字列を結合し、改行する方法は?

    EXCELで二つの文字列を結合し、かつ改行したいと思います。 検索したところ ="a" & CHAR(10) & "b" というのが有りました。 しかし、私のPCでは結合はされますが改行はされません。 原因は何でしょうか。 尚、EXCEL は 97 SR-1 です。(かなり古い・・・(汗)) また、Open Office でも同じでした。

  • 文字を連結して配列に入れるプログラム

    調べている時間がないので、初歩的な質問ですがよろしくお願いします。 文字、「い」、「ろ」、「は」を入力して、これを連結して出来る3文字の文字列の全ての組み合わせ「いろは」「ろはい」....を配列で返すプログラムをC言語で作成するとどうなるのでしょうか。 つまり、ひらがなの入力と文字列の結合と文字列を配列で返すにはどうすればよいかと言うことを教えて欲しいのです。