OleDBを使用して.NETからSQL Server 2005を照会する場合の大文字と小文字の区別
-
02-07-2019 - |
質問
.NETアプリケーションからSQL Serverデータベースに対して実行しているクエリがあり、完了するまでにかなり時間がかかるようです(5分以上)。 C#でテストアプリを作成して、何が長かったのかを確認しようとしました(クエリはすぐに返されるはずです)。
要素を追加してクエリを再構築し、どの部分が非常に時間がかかっているかを確認したため、元のクエリのスペースと大文字と小文字の違いのみが異なるクエリを実際に逐語的に再構築しました。この違いは約100ミリ秒で結果を返しました。
これを見た人はいますか?サーバー(同僚にも同じ問題があるため)またはコンピューターでサービスがオフになっているかどうか疑問に思っています。
これについてお問い合わせいただきありがとうございます。
以下のコードサンプル(最後のクエリの最初の行の違い(fk_source vs. fk _Source):
//Original
OleDbCommand comm = new OleDbCommand("select min(ctc.serial_no) as MIN_INTERVAL from countstypecode ctc, source s, countstype ct, counts c where ct.value_id=c.value_id and s.c_id=ct.fk_source and " +
"ct.timeinterval=ctc.typename and ct.timeinterval in ('15min','1h','1day') and c.time_stamp >= CONVERT(datetime,'01-01-2008',105) and c.time_stamp < " +
"CONVERT(datetime,'01-01-2009',105) and s.c_id = '27038dbb19ed93db011a315297df3b7a'", dbConn);
//Rebuilt
OleDbCommand comm = new OleDbCommand("select min(ctc.serial_no) as MIN_INTERVAL from countstypecode ctc, source s, countstype ct, counts c where ct.value_id=c.value_id and s.c_id=ct.fk_Source and " +
"ct.timeinterval=ctc.typename and ct.timeinterval in ('15min','1h','1day') and c.time_stamp >= CONVERT(datetime,'01-01-2008',105) and c.time_stamp < " +
"CONVERT(datetime,'01-01-2009',105) and s.c_id='27038dbb19ed93db011a315297df3b7a'", dbConn);
解決
これはプロシージャキャッシュの問題であると思われます。ストアドプロシージャの利点の1つは、プランが自動的に保存されることです。残念ながら、キャッシュ内で不適切なプランを取得することは可能です(動的クエリを使用している場合でも)。
楽しみのために、プロシージャキャッシュをチェックし、アドホッククエリを実行し、再度チェックし、異なるクエリを使用して同じクエリを実行したところ、プロシージャカウントが増加することに驚きました。
試してみてください...
SQL Server Management Studioに接続します。
DBCC MemoryStatus
Select Columns... From TABLES.... Where....
dbcc MemoryStatus
Select Columns... From tables.... Where....
dbcc MemoryStatus
ステートメントが変更されると、TotalProcsが変更されることがわかると思います(唯一の変更が大文字と小文字を区別する場合でも)。
統計の更新が役立つ場合があります。それはかなり遅い実行プロセスなので、遅い期間に実行したいかもしれません。
他のヒント
SQL Server 2005を使用しているので、OleDbCommandオブジェクトではなくSqlCommandオブジェクトを使用したことがありますか?
パフォーマンスに影響するクエリの違いは見当たりません-実行間のキャッシュやインデックス/統計の変更はどうですか?統計またはインデックスの変更により、実行計画が変更された可能性があります。
大文字と小文字の区別:データベースが大文字と小文字を区別するように設定されている場合、大文字と小文字は区別されますが、両方のクエリを大文字と小文字を区別するデータベースで実行するには、両方の形式の名前の列が必要です-クエリパーサーは従いますケース-パフォーマンスの違いは発生しません。
まず、クエリが間違っていることを100%確信していますか? SQLサーバーのトレースプロファイルをチェックして、DBでの取得時間を確認します。
次に、同じ数の結果が返されますか。 SQLサーバーではデフォルトで大文字と小文字は区別されませんが、別の方法で設定することもできます。
「5分以上」かかるクエリがある場合、文字列の大文字と小文字が一致するのにかかる100ミリ秒は心配しません。
すべての回答に感謝します。それぞれに順番に回答します。
1)ラス、SQLConnectionの方が良いことに同意しますが、残念ながら、接続の種類を設定することはできません。このクエリをテストするために小さなアプリを作成しましたが、クエリははるかに大きなアプリケーションで動的に作成されます。
2)gbjbaanb、これはサーバーの問題ではないと思います。管理スタジオから両方のクエリをほぼ同時に実行できるため、.net(1.1および2.0)でoledbを実行する場合にのみ問題になるようです。 。プロファイラーを実行し、トレースファイルにより、この方法で呼び出されたときにクエリを完了するのに5分以上かかることが確認されました。
3)Joel Coehoorn、Agreeed、しかし私がここで得ようとしているのは、「なぜ」と言うことです。なぜなら、この問題がどれほど大きく、どこにあるのかわからないからです。
4)Cade Roux、違いは非常に再現性が高いので、同じ結果でテストを連続して実行したため、インデックスの変更やキャッシュの問題ではないと思います実行するSQL Server。
最も完全な回答をいただいたG Mastrosに感謝します。ただし、振り返ってみると、統計の更新がCadeによって提案されました。ただし、G Mastosのソリューションは、私のレベルのSQL Serverの経験により適していました。
皆さんを助けてくれてありがとう!
この一見無害な違いが大きな影響を与える理由を調べます