4

多かれ少なかれ次のように見える約100.000行のテーブルがあります。

id      varchar(20),
omg     varchar(10),
ponies  varchar(3000)

国際文字のサポートを追加する際、ponies3000 (マルチバイト) 文字は nvarchar には大きすぎるため、列を nclob に再定義する必要がありました。

id      varchar(20),
omg     varchar(10),
ponies  nclob 

Java で準備済みステートメントを使用してテーブルから読み取ります。

select omg, ponies from tbl where id = ?

「ponies」列が NCLOB に変更され、他のいくつかのテーブルが nchar 列を使用するように変更された後、Oracle 11g はid列のインデックスを使用する代わりに完全なテーブル スキャンを実行することを決定したため、アプリケーションが停止しました。

クエリにヒントを追加すると、インデックスが使用され、すべてが「問題なく」、または列が varchar の場合よりも少しだけ遅くなります。

次の接続プロパティを定義しました。

 oracle.jdbc.convertNcharLiterals="true"
 defaultNChar=true

ところで、データベース統計が更新されます。

すべてのクエリを調べる時間がなかったので、他のインデックスが無視されているかどうかはわかりませんが、id が nchar ではないため、defaultNChar 設定がオプティマイザーを混乱させているのではないかと心配する必要はありますか? 事実上すべてのクエリにヒントを振りかけるか、すべてのキーを再定義するのはかなり厄介です。

または、「大きな」nclobがロードされるため、完全なテーブルスキャンは重要ではないと見なされます-その仮定は3桁ずれているようで、Oracleはそれよりも賢いと信じたいです。

それとも運が悪いだけ?または、他の何か?ヒントなしで修正できますか?

4

3 に答える 3

3

問題は、jdbc フラグの defaultNChar=true であることが判明しました。

パラメータが nchar/nvarchar として送信された場合、Oracle オプティマイザは char/varchar2 カラムで作成されたインデックスを使用しません。ファントム結果が得られる可能性があるため、これはほぼ理にかなっています。

ほとんどの場合、パラメータが char/varchar2 として定義されたストアド プロシージャを使用しており、クエリが実行される前に強制的に変換されているため、動的 SQL が使用されるいくつかの場所を除いて、この効果に気付きませんでした。

解決策は、データベースを AL32UTF8 に変換し、nchar 列を取り除くことです。

于 2012-01-28T22:07:11.247 に答える
2

統計をやり直したときdbms_stats.gather_table_stats、estimate_percentage> 50%で推定または使用しましたか?その後、100%のestimate_percentageでdbms_statsを使用しなかった場合。

テーブルが3列のみで、これらが返される列である場合、ヒントが何であれ、idインデックスが一意であっても、最適なインデックスは3列すべてです。現状では、explain計画は、一意のインデックススキャンと、それに続くROWIDによるテーブルアクセスによって行う必要があります。3つの列すべてにインデックスを付けると、返されるすべての情報がすでにインデックスに含まれているため、これは一意のスキャンになり、テーブルに再度アクセスして取得する必要はありません。順序はid, omg, ponies、where句でそれを利用することです。これにより、テーブルが効果的に作成index organized tableされ、個別のインデックスを作成するよりも簡単になります。明らかに、後で統計を収集します。

nclobにインデックスを付けることができるかどうかは実際にはわかりませんが、何をしても、列のサイズは影響を及ぼします。これは、ディスクの読み取りが長くなるほど、実行する必要があるディスクの数が増えるためです。

于 2011-10-10T23:26:49.730 に答える
0

申し訳ありませんが、列ポニーを varchar から clob に変更した理由がわかりません。この列の最大長が 3000 文字の場合、代わりに NVARCHAR2 列を使用しないのはなぜですか? 私の知る限り、nvarchar2 は最大 4000 文字を保持できます。

しかし、その通りです。許容される最大列サイズは、各国語文字セットが AL16UTF16 の場合は 2000 文字、UTF8 の場合は 4000 文字です。

于 2011-10-11T06:55:47.180 に答える