Windows XP SP3 の MS SQL Server 2008 R2 には、数百万のレコード データベースがあります。
私の同僚は、このデータベースに直接接続し、妥当な量のクエリを実行する .Net アプリケーションを作成しました。.Net はわかりませんが、このアプリは ODBC を使用して DB に接続しないと確信しています。
一方、コマンドライン python (CPython バージョン 2.7.5) アプリケーションを作成しました。このアプリケーションは、このデータベースに接続し、単純なクエリを実行して、インターネット経由でデータを別の場所に送信します。データベース接続は、pyodbc 3.0.7 ( http://www.lfd.uci.edu/~gohlke/pythonlibs/SQL Server Native Client 10.0
のインストーラー) とドライバーを使用する DSN を使用して行われます。WindowsアプレットConnection Pooling
のタブで、このドライバーの接続プールを無効にしたり有効にしたりしてみました。Data Sources (ODBC)
スクリプトは、データベースから 100 レコードを送信し、接続を閉じて 2 分間スリープしてから、再度実行します。
これらのプログラムは両方とも、db と同じマシン上で常に実行されます。
問題は、定義された DSN を削除すると、.Net アプリが適切に実行されることです (もちろん、python スクリプトは実行されていません)。DSN を再度定義し、python スクリプトを開始して side by side .Net アプリを実行すると、約 5 時間問題が発生しません。しかし、Pythonスクリプトはほとんど問題ありませんが、.Netアプリはdbからタイムアウトを取得し始めます。
これが起こると何がうまくいかないのでしょうか?
編集:
Python スクリプト (ODBC を使用して接続する) は、常に正常に実行されます。しかし、.Net アプリは、数時間後に通常のパフォーマンスよりも遅れます。Python スクリプトを閉じると、.Net アプリがまだ残っています。しかし、Python スクリプト用に定義した ODBC DSN を削除すると、.Net アプリは通常のパフォーマンスに戻ります。とても奇妙です。私が言ったように、私は .Net について何も知らないので、これは .Net アプリ側の非標準コードの結果である可能性があります。おそらく、開いているトランザクション、ロック、接続が多すぎるなどです。レコードを削除してインデックスを再構築することでデータベースのサイズを半分にすると、これまでのところ .Net アプリの問題は解決したようです。
編集2:
Python スクリプトが実行するクエリは次の 2 つだけです。
SELECT TOP 100 FROM tbl_data WHERE id > ? ORDER BY id
と
SELECT * FROM tbl_data WHERE id = ?
通常、最初のクエリは、python スクリプトの実行ごとに 1 回だけ実行されます。2 番目のものは最大 100 回実行されます。id
は主キーであり、インデックスも作成されます。ご覧のとおり、クエリはこれ以上簡単ではありません。最初のクエリでは、プログラム内の結果セット全体を読み取って、DB サーバーでカーソルを開いたままにしないようにしました。また、使用しているドライバーの ODBC アプレットで接続プールをオフにしたため、スクリプトを実行するたびに、DB 接続が破棄され、DB サーバー上のすべてのリソースが解放されているはずです。スクリプトは 2 分間スリープしてから、これを繰り返します。
.Net アプリが実行するクエリは、データベース上のいくつかのトリガーと組み合わされて、はるかに複雑です。そして奇妙なことに、それ自体はほとんど問題なく動作します。しかし、DSN が定義されると、1 つの挿入ステートメントで長い待ち時間が発生し始め、タイムアウトになることがあります。
また、Windows と MSSQL は Microsoft からの最新のパッチで更新されていないことを言うべきだったので、ODBC ドライバーまたは MSSQL 自体のバグであれば、他の人にとっては既に解決されている可能性があります。
編集3
テーブルは PK インデックスでクラスター化されます。現在、データ テーブルには約 150 万件のレコードが含まれています。DBサイズは約160GB。サーバーはハイスペックではありません。Intel Core i7 2600、4GB RAM、プレーン 1TB SATA ディスク ドライブ。