0

2 つの異なる Oracle サーバーに同じデータベースがあり、1 つは 11.2.0.1.0、もう 1 つは 11.2.0.4.0 です。両方のデータベースに同じ 2 つのジオメトリ テーブルがあり、両方のサーバーで次のクエリを実行します。11.2.0.1.0 バージョンの Oracle で実行すると、クエリが数分間実行されて結果が得られます。11.2.0.4.0 で実行すると、同じクエリが約 3 秒間実行され、結果が返されません。

BLPUs テーブルには 3600 万ポイントが保持され、PD_B2 テーブルにはポリゴンが保持されます。ポリゴンに含まれるすべてのポイントを見つけようとしています。他の空間クエリは行を返しますが、Oracle Spatial のドキュメントで提案されているテーブル結合がすべてのポイントを返すのに 15 分かかるのに対し、何時間もかかります。

SELECT /*+ ordered */ a.uprn 
FROM TABLE(SDO_JOIN('BLPUS', 'GEOLOC', 'PD_B2', 'GEOLOC','mask=ANYINTERACT')) c, blpus a, PD_B2 b 
WHERE c.rowid1 = a.rowid 
AND c.rowid2 = b.rowid; 

以下の空間クエリは、11.2.0.4 サーバーで実行すると SDO_ROWIDSET() を返します。

select SDO_JOIN('BLPUS', 'GEOLOC', 'PD_B2', 'GEOLOC','mask=ANYINTERACT')
from dual;

select SDO_JOIN('BLPUS', 'GEOLOC', 'PD_B2', 'GEOLOC')
from dual;

11.2.0.1 サーバーでは、結果が返されます。

11.2.0.4 でははるかに小さなポイント テーブルが機能することを発見したため、SDO_JOIN を使用する場合、11.2.0.1 は大きなテーブルに対応しているように見えますが、11.2.0.4 にはサイズ制限があるようです。

これがなぜなのか、またはSDO_JOINを使用するときにテーブルサイズに実際の制限があるのか​​ 誰か知っていますか?

4

1 に答える 1

0

変ですね。11.2.0.4 で SDO_JOIN が同じように機能しない理由がわかりません。少なくとも私はそのような行動を見たことがありません。私にはバグのように見えます。調査できるように、Oracle サポートにサービス リクエストを提出することをお勧めします。テーブルのダンプ、または少なくとも問題を示す十分に小さいサブセットのダンプを提供する必要がある場合があります。

とはいえ、確認すべき点がいくつかあります: 同じデータベースに 11.2.0.4 パッチを適用しましたか? つまり、テーブルの構造や内容、助成金などに関して何も変わっていませんか?

クエリが行を返さないと言うとき、それはすぐに返されますか? それとも、何も返されずに完了する前に何らかの処理を実行しますか?

PD_B2 テーブルの大きさは?

あなたがするとどうなりますか:

select SDO_JOIN('BLPUS', 'GEOLOC', 'PD_B2', 'GEOLOC','mask=ANYINTERACT')
from dual;

これも何も返さないのですか?

するとどうなるか

select SDO_JOIN('BLPUS', 'GEOLOC', 'PD_B2', 'GEOLOC')
from dual;

どちらも次のようなものを返す必要があります。

SDO_ROWIDSET(SDO_ROWIDPAIR('AAAW3LAAGAAAADmAAu', 'AAAW3TAAGAAAAg7AAC'), SDO_ROWIDPAIR('AAAW3LAAGAAAADmABE', 'AAAW3TAAGAAAAgrAAA'),...)

これは、sqlplus でクエリを実行すると表示されます。[GUI (TOAD や SQLDeveloper など) を使用している場合は、それが表示されない場合があります。これらの GUI はすべて、オブジェクトまたは配列の処理に問題があります。]

しかし、11.2.0.4 テストが非常に迅速に完了するという事実は、おそらく次のような空の結果が返されることを意味します。

SDO_ROWIDSET()

そして、それは何かがうまくいかなかったことを確認します.

さて、あなたの言うことから、 PD_B2 には1行しか含まれていませんか? その場合、SDO_JOIN を使用する理由はまったくありません。単純な空間クエリの方が簡単に記述できます。SDO_JOIN は、結合される両方のテーブルに複数の行が含まれている場合にのみ意味があります。繰り返しますが、テーブルの 1 つが非常に小さい場合 (この場合の PD_B2 テーブルのように)、単純なクエリにフォールバックします。

簡単なクエリは次のようになります。

SELECT a.uprn 
FROM blpus a, PD_B2 b 
WHERE sdo_anyinteract (a.geoloc, b.geoloc) = 'TRUE';

これは 11.2.0.4 で期待するものを返しますか?

また、クエリのコストと使用されるクエリ プランを調べることもできます。sqlplus で、次のようにします。

set timing on
set autotrace traceonly

次に、上記のクエリを実行します。その結果、sqlplus は結果を表示しませんが、出力をフェッチしてフォーマットします。出力しないだけです。最後に、使用されたクエリ プラン、実行統計、経過時間の出力が得られます。それらの結果を質問に追加してください。

アプリケーション内からクエリを実行すると、同様のプロファイルが得られます。130 万行すべてをフェッチすると仮定すると、応答時間とデータベース側のコストは同様です。

ところで、これらの結果をどうしますか? 報告書として出しますか?後で分析するためにテーブルに保存しますか? それらすべてを地図上に表示したくないですか?

明確にするために: SDO_JOIN は、多のジオメトリの一致のみを目的としています。1対多マッチングには、単純な SDO_ANYINTERACT() が必要です。実際のところ、SDO_JOIN は、セットの 1 つが他のセットよりも非常に小さい場合、単純な SDO_ANYINTERACT に自動的にフォールバックします。SDO_ANYINTERACT と同じように実行され、2 つのテーブルへの追加の結合が必要になるため、あなたの状況 (つまり、1 つのオブジェクトに一致するすべてのオブジェクトを検索する場合) で SDO_JOIN がどのように高速になるかわかりません。

元の問題に戻ると、 11.2.0.1 と 11.2.0.4 の間の SDO_JOIN の動作の違いは、IMO は間違いなくバグであり、Oracle サポートに報告する必要があります。

于 2015-02-25T22:37:03.247 に答える