2009-08-27 6 views
5

こんにちは、私は、テーブルの主キーにTO_NUMBER()を使用して他のテーブルを結合するビューを含むOracleシステムへのクエリを持っています。JDBCでJavaでのクエリが遅いが、他のシステムでは実行されない(TOAD)

TOADを使用してクエリを実行すると、クエリは非常に高速です(800回のregに対して1秒)。私は、JDBCの文字列リテラル(パラメータ化されていないクエリ)でjavaプログラムで同じクエリを行う場合、時間も良いです。

しかし、私がPreparedStatementによってパラメトリッククエリを使用する場合、クエリは同じレジスタをフェッチするのに1分かかります。私は定数値を使用すると、パラメータを使用するよりも別の実行計画が生成されることを知っています...しかし、私はビューの結合でTO_NUMBER関数を削除すると、パラメトリッククエリも高速です。

  • パラメータ/ TO_NUMBER()共用体は、結合テーブルのPKインデックスを使用できませんか?
  • これを解決するための回避策があります(クエリとTO_NUMBER関数のパラメータが必要です)。

P.D.私の悪い英語のために泣いてしまいました

+0

は分割されたテーブルですか? – skaffman

答えて

1

追加情報なしでは、インデックスにto_number()関数を使用していないと仮定できます。 this SO questionに示すように、型変換によってオプティマイザが索引を使用できなくなる可能性があります。

一般に

  • あなたは、列(すなわち:to_number(id))に機能を追加することが可能である場合、オプティマイザは
  • 、その列に定期的にインデックスを使用することができなくなり、生の列を使用する必要があります。 exempleについて:あなたが使用する必要があります代わりにWHERE trunc(col) = DATE '2009-08-27'の:WHERE col >= DATE '2009-08-27' AND col < DATE '2009-08-28'
  • をあなたが本当に列に関数を適用する必要がある場合、あなたはJava変数のデータ型は、パラメータに渡されたことをfunction-based index
+0

私は、列の関数を使用すると列インデックスの使用を妨げる可能性があることを知っていますが、クエリがパラメータ化されたときにのみ起こるということは珍しいことです。 – Telcontar

+0

@Telcontar:または動的に構築されたSQLを使用して)、パラメータのデータ型が異なります。これにより、暗黙的な変換のために、パラメータ化されたクエリの計画が最適ではない状況が発生する可能性があります。あなたは、この問題を引き起こす簡単な質問の例を教えてもらえますか? –

+0

クエリは、4つの値は、動の どこENTIDAD = 7777 AND TO_NUMBER(CFPERIOD)= TO_NUMBER(251)AND CFSUBGRP = 'S0000' AND ID_VERSION = 6 ビュー使用倍数と結合V_DAT_AJPR_CON_DESCRIP_C FROM SELECT *です他のフォームCFPERIOD、ID、FIELD_1、... FIELD_NのテーブルとPKは(CFPERIOD、ID) とビューとの結合は TO_NUMBER(V.CFPERIOD)= TO_NUMBER(T.CFPERIOD)であるAND V .ID = T.ID – Telcontar

1

チェックを使用することができますOracleデータ型と互換性があります。リテラル文字列問合せOK、PL/SQLでのテストケース(日付)バインドOK、Javaコードの不一致(OK)でないJava DIMESTAMPをOracle DATE列と比較していたバインド変数に渡したときに、

[編集] 元の投稿から追加情報がありましたと思います。異なる環境(JavaとToad)からのクエリのわずかに異なるフォーム(バインドとリテラル)で何が起こっているのかを理解する最善の方法は、実行中にトレースを有効にし、結果のトレースファイルから実行パスを比較することです。これには、ファイルを取り出すためにデータベースホストにアクセスする必要があります。ヒキガエルで

  • 、SQLコマンドの対話型SQL ウィンドウ(私はヒキガエルを使用していないが、私はあなたが私が何を意味するかを理解するだろう 確信している)と 問題を開いて「真のセッション セットSQL_TRACE =を変更「
  • クエリを実行します - 次のようなクエリ にコメントを追加するには良い アイデアだろう 『Javaのテストのためにリテラル* /』
  • と/ *ヒキガエル、発行したテストケース を構築"セッションを変更...「 声明し、クエリを実行します 再び、 にクエリにコメントを追加するJava テストから来るとしてそれを識別
  • はオフトレース を回すことを心配しないでください - 。。これはどうなるとき セッションが切断され、いくつか 例では、トレースを停止 の切断法が好ましい。
  • データベースホスト上のトレースファイルは、 『USER_DUMP_DEST』のような名前 五$パラメータから 値を選択する」ことである場所を見つけます"
  • クエリコメント文字列
  • を検索することによって、.trcのファイルを検索し、トレース ファイルを処理するためにOSから コマンドラインをTKPROFユーティリティを使用して - 「TKPROF filename.trc TKPROF filename.out」
  • を/調べ実行パスを表示し、表示された時間は 回です。
+0

データ型の比較は数字と文字列の間にあり、文字列の中にはビューのテーブルから削除できない0の文字列があります(私はそれらに書き込むことはできません) – Telcontar

+1

私はいくつかを追加しました私の中の情報実際に起こっていることを分析するのに役立つ執行を追跡することについての元の回答。 – dpbradley

+0

Sry私はこの質問を忘れてしまいましたが(すでに未回答ですが)、あなたが提案するテストはできません。私はdbaではなく、テーブル/ビュー、プロシージャ、パッケージのみを作成できます...しかし、 。私はそれをDBAに渡しますが、彼は何もしないと思います – Telcontar

0

必ず誰かがプロパティを設定していないことを確認してくださいoracle.jdbc.defaultNChar =真

これは時々ユニコードの問題を解決するために行われますが、それはすべての列がnvarcharsとして扱われることを意味しています。 varchar列に索引がある場合、oracleは文字エンコーディングを変換する関数を使用する必要があるため、索引は使用されません。

関連する問題