コードと SSMS のクエリ パフォーマンスの不一致
SQL Server Management Studio (SSMS) ではスムーズに実行されるクエリが、次の場合に過度に遅くなることがあります。コード内で実行されます。最近のコード開発中にこの矛盾が発生したため、根本的な原因の調査が必要になりました。
コードの実装
クエリの実行に使用される C# コードは次のとおりです。
using (var conn = new SqlConnection("Data Source=backend.example.com;...")) { using (var ada = new SqlDataAdapter(sqlCommand, conn)) { ada.SelectCommand.Parameters.AddWithValue("@clientID", ClientID); ada.SelectCommand.Parameters.AddWithValue("@dt", dtpFilter.Value); conn.Open(); Logs.Clear(); ada.Fill(Logs); // Time out exception for 30 sec limit. } }
SSMSクエリ
C# コードから抽出された同一のクエリが SSMS で直接実行されます:
SELECT [PK_JOB],[CLIENT_ID],[STATUS],[LOG_NAME],dt FROM [ES_HISTORY] inner join [es_history_dt] on [PK_JOB] = [es_historyid] Where client_id = @clientID and dt > @dt and (job_type > 4 or job_type = 0 or job_type = 1 or job_type = 4 ) Order by dt desc
分析
検査後, 2 つのクエリの間には微妙な違いがあります。 SSMS バージョンでは、@clientID パラメーターは VARCHAR として宣言されますが、C# コードでは、AddWithValue メソッドを使用して追加されます。通常、.NET 変数の型に基づいてデータ型が割り当てられます。この場合、ClientID 変数の型は文字列であり、SQL Server の NVARCHAR にマップされます。
影響
この違いは、クエリのパフォーマンスに大きな影響を与えます。 NVARCHAR パラメーター タイプでは、SQL Server がインデックス付き列に基づいて行を迅速に見つけるために使用する重要な最適化手法である検索引数 (SARG) フィルターを使用できません。その結果、C# コードのクエリはテーブル スキャンの実行を強制されますが、これはインデックス シークよりもはるかに効率が低くなります。
解決策
矛盾がある場合は、C# コードの @clientID パラメーターに VARCHAR データ型を明示的に指定する必要があります。これは、次の構文を使用して実現できます。
ada.SelectCommand.Parameters.Add("@clientID", SqlDbType.VarChar, 200).Value = ClientID;
パラメーターのデータ型が SSMS クエリで宣言されたものと確実に一致するようにすることで、アプリケーションはパフォーマンスの低下を回避し、短時間でクエリを実行できます。効率的な方法。
以上がSQL Server クエリが SSMS では速いのに、C# コードでは遅いのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。