出産前後の痔にはご注意!

業務でJavaとDB(DB2)を使用しています。
最近、SQL関数を使用すべきか否かでちょっと悩んでいます。
SQL関数は確かに便利ですが、使いすぎるとレスポンスが悪くなる、ということはあるのでしょうか?
今はSQLは出来るだけシンプルにして、Javaで補っています。
(例えばGraphic項目から全角スペースを取り除く場合はSQL関数のRTRIMを使わず、DBから取り出した後にJavaで取り除く、など)
ご指導よろしくお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (4件)

>私が知りたいのはコーディング時、SQL関数(RTRIM、nullだったら別の値に置き換えるValue関数など)をふんだんに使って問題ないのか、それともSQLは最小限にしてデータの編集などはJavaで行ったほうがいいのか、ということです。



RTRIMに関しては特に性能落ちる要素が見当たりませんので、使って良いと思いますが、後はプロジェクトでDB担当している人に聞いたほうが良いと思います。
言えるのは関数によってはインデックスを使いようがないケースが出てくるので性能が出ない場合があるということです。

どんな関数を使えばインデックスを使わないかはBtreeインデックスの仕組みを考えれば大体想像はつくと思いますが、分からないうちはアクセスパスとか見て検証すれば良いと思います。

DB得意な人から見ればSQLで解決したほうが良い問題もJAVAが得意な人から見ればJAVAで解決したほうが良いということもあると思います。

僕はDBよりなのでSQL関数はじゃんじゃん使うほうです。
    • good
    • 0
この回答へのお礼

なるほど・・・どうもありがとうございます。
今後のコーディングの指針とさせて頂きます。

お礼日時:2005/03/31 06:34

#2です。


少し補足します。

統計情報(runstatsコマンド)はとっていますか?
もしやっていない場合はrunstatsコマンドを実行することでパフォーマンスが改善する場合が多いです。

runstats on table <schema>.<table> and indexes all
    • good
    • 0
この回答へのお礼

情報、どうもありがとうございます。
ただ、私はDBのカスタマイズは業務ではやっていないです。
私が知りたいのはコーディング時、SQL関数(RTRIM、nullだったら別の値に置き換えるValue関数など)をふんだんに使って問題ないのか、それともSQLは最小限にしてデータの編集などはJavaで行ったほうがいいのか、ということです。

お礼日時:2005/03/30 23:21

概ね#1さんの言うとおりだと思いますが・・・。



RTRIM()は大概の場合インデックスを使ってくれると思います。
    • good
    • 0

使い方によります。



Aにインデックスが張ってあるとき、

○ select A from テーブル where A=RTRIM('123 ')
× select A from テーブル where RTRIM(A)='123'

下の場合、インデックスが設定されている項目に関数を使用すると、インデックスが使用されなくなります。
このため、速度低下が起こります。
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

関連するカテゴリからQ&Aを探す

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qwhere句中のtrim関数について

いつもお世話になっております。

今回は標題の件について、ご教授下さい。

カラム「XXX_CODE」はCHAR(3)の項目です。

この項目が半角スペース(△)のものを条件としてレコードを引き当てたいときに、以下のSQLではうまくデータが取得できません。

trim関数の使い方に誤りがあるのでしょうか。

◆データ
XXX_NO    XXX_CODE
--------------------------------
111     100
222     △△△
333     200

◆SQL
select XXX_NO from hoge where trim(XXX_CODE) = ''

◆結果
該当レコードなし
(本来なら「XXX_NO = 222」のデータを取得したい)

初歩的なことかも知れませんが、ご回答頂ければ幸いです。

よろしくお願いいたします。

Aベストアンサー

空文字はNULLと判定されますので、IS NULLを使用して
select XXX_NO from hoge where trim(XXX_CODE) IS NULL
でやってみて下さい。

Qupdate文で改行を入れる

こんにちは。
いつもお世話になっています。

update文を使用して、データに改行を入れたいのですが、どうすればよいでしょうか。

対象列のデータ型はVARCHAR2です。

例えばSQLPLUSから、
SPL>update 「テーブル名」set 「対象列」='あ改行い改行う改行'
を投入し、そのあと
select 「対象列」 from 「テーブル名」
とすると
SQL>あ
SQL>い
SQL>う
と出てくればよいんですが、
SQL>update 「テーブル名」set 「対象列」='あ\nい\nう\n'
としても
SQL>あ\nい\nう\n
と、「\n」が文字列としてでてきてしまいます。

SPL>update 「テーブル名」set 「対象列」='あ
2い
3う'
と投入すると、期待通りになるのですが、
そうではなく一行にまとめたいのですがどうすれば良いでしょうか。

Oracle9iを使用しています。
宜しくお願いいたします。

Aベストアンサー

こんにちわyukio200263さん
以下のSQL文でどうでしょうか?

UPDATE 「テーブル名」
SET 「対象列」= 'あ' || CHR(13) || CHR(10) ||'い'

ちょっと長くなってしまいますが、一行で可能です。

Qダブルクォーテーション囲いカンマ区切り形式で保存したい

お願いします。
エクセル2000使用してます。
【質問1】
"名前A","ナマエA","09011111111","aaa@docomo.ne.jp"
"名前B","ナマエB","09011111112","bbb@docomo.ne.jp"
"名前C","ナマエC","09011111113","ccc@docomo.ne.jp"
このように、ワークシートをダブルクォーテーション囲いカンマ区切り形式で保存するにはどうすればよいでしょうか。

【質問2】
上記のデータを読み込むときに電話番号部分の先頭の0が取れてしまうの防ぐために、ファイルの拡張子をtxtにリネームしておいて、エクセルから開くときにウィザードで列のデータ形式を文字列と指定しています。もっと簡単な方法が教えてください。(頻繁にファイルを開くので。。。)

Aベストアンサー

1.マクロを使わないと出来ません。
  こんな感じです。
 Open "CsvFileName.csv" for Output as #1
 For Row = 1 to 10
  For Col = 1 to 10
   Select Case Col
    Case 1
     Print #1 Chr$(&H22) & Cell(Row, Col).Text & Chr$(&H22);
    Case 2
     Print #1 Chr$(&H22) & Cell(Row, Col).Text & Chr$(&H22);
    Case Else
     Print #1 Cell(Row, Col).Text;
   End Select
   If Col = 10 Then
    Print #1, ""
   Else
    Print #1, ",";
   End If
  Next Col
 Next Row
 Close #1

2.マクロを使えば自動化できます。
「データ」メニューの「外部データの取り込み」で「テキストファイル」を指定してCSVファイルを選択します。
テキスト取り込みウィザードで列のデータ形式を文字列と指定します。
上記の操作を「マクロの記録」でマクロにしてから
実用になるようにマクロを修正します。

1.マクロを使わないと出来ません。
  こんな感じです。
 Open "CsvFileName.csv" for Output as #1
 For Row = 1 to 10
  For Col = 1 to 10
   Select Case Col
    Case 1
     Print #1 Chr$(&H22) & Cell(Row, Col).Text & Chr$(&H22);
    Case 2
     Print #1 Chr$(&H22) & Cell(Row, Col).Text & Chr$(&H22);
    Case Else
     Print #1 Cell(Row, Col).Text;
   End Select
   If Col = 10 Then
    Print #1, ""
   Else
   ...続きを読む

QSQLで違うテーブルの値を比較して値に差があるレコードを抽出したいので

SQLで違うテーブルの値を比較して値に差があるレコードを抽出したいのですがヒントをいただけないでしょうか。
下に例を作ってみました。(テキストに貼りなおしてもらうと見易くなると思います)
<Aテーブル>
A1A2A3A4A5
------- ------- ------- ------- ----------
XXXXXXX XX1ABC32009/05/08
WWCWWCW WW2CCB12008/03/21
DDDDDDD DD1JPN52007/08/08
GGGGGGG GX9SOX21977/01/04
FFFFFFF USJNPB32001/09/11


<Bテーブル>
B1B2B3B4B5
------- ------- ------- ------- ----------
XXXXXXX XX1ibichaoshimu2002/07/05
XXXXXXX XX1takeshiokada2005/07/15
XXXXXXX XX1kamoshu1857/09/25
WWCWWCW WW2waowao2008/10/22
DDDDDDD DD1uihhh2006/06/30
DDDDDDD DD1jojoj x5xx1999/09/09
DDDDDDD DD1momohara2005/03/07
DDDDDDD DD1itaiu-2003/12/22
DDDDDDD DD1komanogoal2007/04/26
GGGGGGG GX9 damerecord2009/11/14
FFFFFFF USJ ikitai1995/08/15
FFFFFFF USJ sstebuspi2004/01/05
FFFFFFF USJ bbpp2009/08/23

A1とB1は主キー、A2とB2は副キーです。
Aテーブルの「A4」カラムにはBテーブルのレコード数を持っています。(主キー、副キーが同じものの)
しかし、よくよく見るとAテーブルの「GGGGGGG」のA4には「2」のはずなのにBテーブルには実際にレコードは1つしかありません。
こういう状態になってしまっているのを割り出したいのですがどのようにA4とBテーブルで数があってないものを抽出できるでしょうか。
よろしくお願いいたします。

SQLで違うテーブルの値を比較して値に差があるレコードを抽出したいのですがヒントをいただけないでしょうか。
下に例を作ってみました。(テキストに貼りなおしてもらうと見易くなると思います)
<Aテーブル>
A1A2A3A4A5
------- ------- ------- ------- ----------
XXXXXXX XX1ABC32009/05/08
WWCWWCW WW2CCB12008/03/21
DDDDDDD DD1JPN52007/08/08
GGGGGGG GX9SOX21977/01/04
FFFFFFF USJNPB32001/09/11


<Bテーブル>
B1B2B3B4B5
------- ------- ------- ------- ----------
XXXXXXX XX1ibichaoshimu200...続きを読む

Aベストアンサー

SELECT A.* FROM Aテーブル A
INNER JOIN
TABLE(SELECT B1,B2,COUNT(*) SU
FROM Bテーブル GROUP BY B1,B2) B
ON A.A1=B.B1 AND A.A2=B.B2
AND A.A4<>B.SU

または

WITH B(B1,B2,SU) AS
(SELECT B1,B2,COUNT(*) SU
FROM Bテーブル GROUP BY B1,B2)
SELECT A.* FROM Aテーブル A
INNER JOIN B ON A.A1=B.B1
AND A.A2=B.B2 AND A.A4<>B.SU

こんなのでどうでしょうか?
後者の方が標準的(他のDBシステムでも
使える可能性が高い)かと思います。

Qsqlplusで表示が変なので、出力を整形したい。

いつもお世話になっています。

サーバにアクセスしてsqlplusで、
データを調べたいのですが、
出力形式が見づらくて困っています。

よくわからいのですが、
---------------------------
カラム名1
---------------------------
カラム名2
---------------------------
カラム名3
---------------------------
1の値 2の値
3の値
---------------------------
カラム名1
---------------------------
カラム名2
---------------------------
カラム名3
---------------------------

上記のように意味不明な形式で出てきます。

例えばこんな風に

select カラム1,カラム2,カラム3 from hoge;

カラム1 1の値
---------------------------
カラム2 2の値
---------------------------
カラム3 3の値

等のように分かりやすく表示できないでしょうか?

ちなみにOracle9iR2を使用しています。
sqlに関するツールは使用できないルールでして、あくまでsqlplusのコマンド上でみやすくしなければなりません。

分かりづらくですいませんが、皆さま、ご教授お願いします。

いつもお世話になっています。

サーバにアクセスしてsqlplusで、
データを調べたいのですが、
出力形式が見づらくて困っています。

よくわからいのですが、
---------------------------
カラム名1
---------------------------
カラム名2
---------------------------
カラム名3
---------------------------
1の値 2の値
3の値
---------------------------
カラム名1
---------------------------
カラム名2
---------------------------
カラム名3
-----------------------...続きを読む

Aベストアンサー

SQLPLUSを起動して、

SQL>set linesize 列数

でどうだ。

SQL>show linesize

で確認ができる。

QOracle(オラクル)で、日付時刻型の検索方法について

質問させていただきます。
データベースはオラクルを使っていて、
SQL文で、抽出するときにエラーが出て困っています。

日付時刻型が「2005/05/26 19:13:00」という感じで入ってます。
2005/05/26 を抽出したいのですが、
BETWEEN '2005/05/26 00:00:00' AND '2005/05/26 23:59:59'

だと、エラーでできません。
どなた様か、ご教授よろしくお願いしますm(_ _)m

Aベストアンサー

日付検索を行う場合は、以下のように書式を含める必要があります。

col BETWEEN TO_DATE('2005/05/26 00:00:00','YYYY/MM/DD HH24:MI:SS') AND TO_DATE('2005/05/26 23:59:59','YYYY/MM/DD HH24:MI:SS')

ただ、厳密には

col >= TO_DATE('2005/05/26', 'YYYY/MM/DD')
AND
col < TO_DATE('2005/05/27', 'YYYY/MM/DD')

と書くべきでしょうね。

Qbatファイルからsql文実行

クライアントOS:WIN2000
Oracle:9i(サーバ(UNIX)上にあります)

現在、クライアントからbatを起動し、SQL文を投げ、結果を取得したいと思っております。
(SQL文は単純にTBLをカウントしているだけです)

・batの中身
sqlplus %UID%/%PASS%@%SID% @test.sql > output

結果は取得出来るのですが、余分な情報も結果に出力されてしまいます。結果のみを出力させるにはどうすればよろしいでしょうか?

・余分な情報
Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 - Production
に接続されました。

Aベストアンサー

sqlplus に -S オプションを追加してみればどうでしょうか。

参考URL:http://biz.rivus.jp/sqlplus_overview.html

Q全角空白のTRIMができない・・・

文字列の前後の全角空白を除去するのに
trimが使えると思っていたのですが、できませんでした。
(半角なら取れるのですが・・・)

select trim(' あいうえお ') from dual;

何とか前後の全角空白を除去したいのですが、
何か方法はないでしょうか。

Aベストアンサー

こんな感じ。
select trim(' ' from ' あいうえお ') from dual

第2引数で消したい文字を指定できます。
select rtrim(ltrim(' あいうえお ',' '),' ') from dual

Qlikeとsubstrの使いわけについて

現在、大量データを扱うマスタDB(oracle)に対し、オンライン業務にて曖昧検索を実施する機能を開発しています。
性能を十分に考慮したsqlを組む必要があり、以下のいづれを選択するか判断しかねています。
それぞれの意味合いを十分に理解できておらず申し訳ございませんが、どなたかご教示をお願いします。
■要件
 曖昧検索をして検索を行う。
 例)漢字氏名が”林”で始まるお客様を一覧表示
■実現するためのSQL文
 案1)select~ where 漢字氏名 like ’林%’; 
 案2)select~ where substr(漢字氏名,0,2)=’林’;
 ※漢字氏名の型はvarchar2です。

処理時間(oracleのコスト的には)どちらも変わりませんかね?
以上、宜しくお願いいたします

Aベストアンサー

漢字氏名列に索引がある場合、LIKE検索では、レンジスキャン可能です。
substrなど関数を介す場合は、一般的には索引を用いません。
ただし、substr関数を使うことが分かっている場合は、ファンクション索引を
使うことでファンクション索引に合致する検索であれば索引が利用できます。
仮に索引がない場合、LIKEでもsubtr関数でもフルスキャンですから、
substr関数のオーバーヘッド程度の違いしか生まれません。

索引の有無で変わってくるので、実際にどちらが効果的かは、実行計画を自ら比較してください。

Qテーブルからのselectにおいてデータの有無により結果をわけたい

id | point
----+-------
1 | 10
2 | 9
3 | 5
....
というテーブルがあるとします.
idを指定してpointを得たいのですが、そのidがこのテーブルに存在しない場合は空の結果ではなく0を返したいのです.
plpgsqlなどを使いif文で場合分けすればできることはわかっているのですがSQL文だけで(それもできれば1文で)これを実現する方法はあるでしょうか?
よろしくお願い致します。

Aベストアンサー

変則的ですが、これでよければidがユニークでなくても大丈夫ですし、集合関数を使わなくてもOKです。

select dm.id,case when ex1.point is null then 0 else ex1.point end from
(select ? as id) as dm left join ex1 on dm.id = ex1.id;

?を適当に変えてください。
chukenkenkouさんの発想はこれですよね。


人気Q&Aランキング