trapemiyaの日記

hatenablogが新しくなったんで新規一転また2019年1月からちょこちょこ書いてます。C#中心のプログラミングに関するお話です。

SQL ServerからOracleへのリンクサーバーのパフォーマンス

Oracleへのリンクサーバーのテーブルを読む際に、とんでもなく遅いパフォーマンスのテーブルに出会った。
1つのテーブルから2件のレコードを読むだけなのに1分20秒もかかる。
一方で、6つぐらい外部結合していても数秒で表示されるクエリもある。
レコード数は前者は約210万4千件、後者は約5万件である。この違いなのかもしれない。
上記のSQLはドット表記やらフォーパート表記とか呼ばれたりするようだ。
いわゆるSQL ServerSQL文でOracleから抽出する。どうもこの時にOracleでインデックスが使われなかったり、データをローカルに持っきて
そこでフィルターをかけて抽出されていると言った記事をいくつか見た。

で、解決策はOpenQueryを使う方法のようで、Accessで言えばパススルークエリのようなものらしい。
こちらはOracleSQLを直接送ってOracleで処理してもらうので、Oracle用のSQLを書く必要がある。

このOpenQueryを試したところ、上記の1分20秒かかっていたものが1秒もかからないぐらいで終わるようになった。

比較的件数の少ないテーブルだと、ドット表記とフォーパート表記はあまり変わらないのかもしれない。
事実、私のところでは今のところそのように感じている。
もう少し研究してみるが、面倒だがOpenQueryで書いておくとパフォーマンス的には間違いないのかもしれない。
ちなみにOpenQueryではパラメータが使えないので、文字列連結でSQL文を組み立てることになる。
よって、SQLインジェクションには注意する必要がある。

select * from openquery(リンクサーバー名, oracleのSQL文)

openquery内のリンクサーバー名は、4パートではなく2パートで構成されたものなので注意。
言い換えると、前者はドットが3つで4パート、後者はドットが1つで2パートである。

#ちなみにSQL Serverへのリンクサーバーは今のところ高速に動作する。もう少し開発を進めていかないとわからないが・・・