5

次のクエリは、TOAD (ネイティブの Oracle ドライバーを使用) を使用して Oracle 11 に対して直接実行すると効率的に機能します。

select ... from ... where ...
and srvg_ocd in (
  select ocd
   from rptofc
  where eff_endt = to_date('12/31/9999','mm/dd/yyyy')
    and rgn_nm = 'Boston'
) ...
;

を介して SQL Server 2008 から同じ Oracle データベースに渡された場合、まったく同じクエリが返されることはありませんopenquery()。SQL Server には、Oracle Provider OLE DB ドライバーを使用して Oracle データベースへのリンクがあります。

select * from openquery( servername, '
  select ... from ... where ...
  and srvg_ocd in (
    select ocd
     from rptofc
    where eff_endt = to_date(''12/31/9999'',''mm/dd/yyyy'')
      and rgn_nm = ''Boston''
  ) ...
');

妥当な時間内にクエリが返されず、ユーザーがクエリを強制終了します。最終的に正しい結果が返されるかどうかはわかりません。

直接の TOAD クエリが効率的に機能し、openquery()バージョンが「決して」返されないこの結果は再現可能です。

を少し変更するとopenquery()、正しい効率的な結果が得られます。 に変更eff_endttrunc(eff_endt)ます。

それは良いことですが、変更が必要なようには見えません。

openquery()TOAD とopenquery()動作にどのような違いがあるのでしょうか?

私たちが気にする理由は、Oracle に直接アクセスする TOAD を使用して複雑なクエリを頻繁に開発するためです。クエリが機能して最適化されたらopenquery()、SQL Server アプリケーションで使用する文字列に変換します。openquery()クエリが直接クエリとして機能していることがわかっているときに、クエリが突然失敗することは非常に厄介です。次に、試行錯誤しながら回避策を探す必要があります。

2 つのシナリオの Oracle トレース ファイルを確認したいのですが、Oracle サーバーは別の組織内にあり、Oracle DBA から協力を得られません。

ドライバー、TOAD、または???を知っている人はいますか?不一致を説明できる問題はありますか?両方の方法で常に同じ結果が得られるように問題を解決する方法はありますか?

4

3 に答える 3

1

クエリを受け取った後のデータベースの動作を確認するために確認できる基本的な事項を次に示します。最初に、openquery を使用してクエリを実行するときと、実行計画が TOAD で同じであることを確認します。以下を使用して、TOAD でクエリを自分で計画できます。

explain plan set statement_id = 'openquery_test' for <your query here>;

select *
from table(dbms_xplan.display(statement_id => 'openquery_test';

次に、誰かに openquery() を使用してクエリを開始してもらい、実行する v$ テーブルを表示する権限を持つ人に依頼します。

select sql_id from v$session where username = '<user running the query>';

(同じユーザーとの接続が複数ある場合は、クエリを実行しているセッションを表す行を分離するために、追加の属性を見つける必要があります。)

select *
from table(dbms_xplan.display_cursor('<value from query above'));

それらが同じように見える場合は、データベースの待機のチェックに進み、何がスタックしているかを確認します。

select se.username
     , sw.event
     , sw.p1text
     , sw.p2text
     , sw.p3text
     , sw.wait_time_micro/1000000 as seconds_in_wait
     , sw.state
     , sw.time_since_last_wait_micro/1000000 as seconds_since_last_wait
  from v$session se
       inner join
       v$session_wait sw
          on se.sid = sw.sid
 where se.username = '<user running the query>'

;

(繰り返しますが、同じユーザー名のセッションが複数ある場合は、関心のあるものに絞り込むために別の属性が必要になります。)

プランが異なる場合は、その理由を調べる必要があります。プランが同じ場合は、待機しているもの (クライアントへの SQL*Net メッセージなど) とその理由を調べる必要があります。

于 2013-08-09T20:17:30.370 に答える
1

少し前にこれを尋ねたことは知っていますが、あなたの質問に出くわしました。

私は同意します、それらは同じであるべきです。明らかに違いがあります。違いがどこにあるのかを見つける必要があります。

入力しながら大声で考えています...

select * from openquery の代わりにいくつかの列を指定するとどうなりますか?

何行が返されることになっていますか?

オラクルの選択で、返される行を制限するとどうなりますか?

openquery がタイムアウトするまでの時間は?

TOAD と SS は同じマシン上にありますか? SS に RDP 接続し、そこからヒキガエルを実行していますか?

彼らは同じドライバーを使用していますか?ビットを含む?(32/64)バージョン?

彼らはオラクルで同じアカウントを使用していますか?

trunc()を使用すると違いが生じるのは興味深いことです。[eff_endt] は返されたフィールドの 1 つだと思いますか?

SS がすべての行を取得しているかどうか疑問に思っていますが、日付変換を行う際に窒息しています。Oracle の日付型は、ss が表示する前に ss 日付型に変換する必要がある場合があります。

日付フィールドが(n)varchar. ss は、オラクルから返された日付を変換せずにそのテキスト フィールドにダンプする可能性があると考えています。

何かのようなもの:

insert into mytable(f1,f2,f3,datetimeX)
select f1,f2,f3,datetimeX from openquery( servername, '
  select f1,f2,f3,datetimeX from ... where ...
  and srvg_ocd in (
    select ocd
     from rptofc
    where eff_endt = to_date(''12/31/9999'',''mm/dd/yyyy'')
      and rgn_nm = ''Boston''
  ) ...
');

ヒキガエルまたは ss がオラクルに送信する前にクエリ文を変更している場合はどうでしょうか。Wireshark を起動して、toad と ss が実際に何を送信しているかを確認できます。

これが解決されれば、非常に興味があります。私は ss を oracle に頻繁にリンクしていますが、この問題に遭遇したことはありません。

于 2013-08-06T06:29:43.357 に答える
0

Oracle 10g および 11g テーブルに接続する MS Access (2013) を介して OLEDB を使用すると、Oracle テーブルのインデックスまたは主キーが常に正しく認識されるとは限らないという違いに気付きました。MS Access 2000 データベース (odbc を使用) を介した同じクエリは正常に機能し、インデックスとキーに問題はありませんでした。OLEDB バージョンを修正するために私が見つけた唯一の方法は、すべてのキー フィールドを SELECT に含めることでした。これは、SSMS / OpenQuery(...) も試すオプションかもしれません。

それに加えて...次のようなOPENQUERYの代替手段を試すことができます。

  • 4 部構成の名前: SELECT ... FROM Server..Schema.Table
  • AT を実行: リンク サーバーで EXEC ('select...')

しかし、OLEDB プロバイダーがネイティブの Oracle プロバイダーとは異なる動作をする理由については、プロバイダーは同一ではなく、ネイティブ プロバイダーは、より一般的な OLEDB プロバイダーよりも Oracle の癖を克服する可能性が高くなります。

于 2013-08-09T21:12:24.663 に答える