0

一部のプロジェクトで、SQL Server 用の再利用可能なデータ アクセス レイヤーを作成しています。decimal.NETをパラメーターとしてクエリに渡す適切な方法を見つけるのに問題があります。最も明白な方法:

cmd.Parameters.AddWithValue("@P0", parameterValue);

ほとんどうまくいきます。値は DB に適切に格納されますが、SqlClient は実際の値から正確な型を推測するため、アプリケーションが 12345.678 を渡すと、@P0 を として宣言しNUMERIC(8,3)ます。まったく同じクエリが他の値で使用される場合、その値の精度と位取りが宣言されます。私にはまだ知られていない理由で、SQL Server からこれらのクエリは等しくなく、それぞれが別々のエントリを取得しsys.dm_exec_cached_plansます。まったく同じ問題がありますstring-長さごとに異なるクエリプランがあります。

私たちのアプリケーションの中には、1 分あたりかなりの数のレコードを書き込み、それぞれに 5 ~ 10 個のdecimal値があり、その範囲は大きく異なります (一部のセンサー データ、一部の通貨値)。ほぼそれぞれINSERTが独自のクエリ プランを取得し、1 日後には同じクエリ プランの 10 万を超えるバージョンがキャッシュされ、数 GB をはるかに超える RAM が消費されます。

対処する私の考えは、すべての可能なタイプをいくつかの任意に選択されたタイプに結合することです。の場合decimal、精度が 20 より小さい場合は 20 に設定します。精度が 20 より大きい場合は、実際の精度よりも 4 で割り切れる最小値 (例: 24、28、32、36) として設定します。スケール (最小 2、次に 2 ずつステップ) と文字列 (最小 128、次に 2 の累乗) についても同様です。この方法で問題を制御できるようです。クエリごとに 100k ではなく約 100 種類のプランがあり、SQL Server は無駄なプランではなくバッファ プールにメモリを使用します。

このアプローチがうまくいかない可能性はありますか?SqlClient と でロードされたクエリを使用する場合、クエリ プランのキャッシュを制御下に置くためのより良い方法はありますdecimalsか?

私ができないことのリスト:

  • ストアド プロシージャを使用します。この DAL の目的は、多くの DBMS (現時点では SQL Server、MS Access、Firebird、Oracle) の抽象レイヤーを作成することであるためです。
  • 仲間のチームメイトに、どうにかして各変数で実際の型を渡すように強制します-それは残酷だからです。
  • この DAL を破棄し、単純な古い DbProviderFactory を使用して、1990 年のようにパラメーターを作成します。これは、この DAL が SQL 方言のクエリ作成、DB 構造の作成なども処理するためです。
  • この DAL を破棄し、NHibernate のような「適切な」DAO を使用してください。
  • この質問を dba.stackexchange.com に送信してください。これは、SQL Server 自体の問題ではなく、SqlClient とその使用方法の問題であるためです。
4

1 に答える 1

2

SQL ドライバーにパラメーターのサイズ、スケール、および精度を決定させるという重要な問題をここで正しく特定しました。パラメータの精度/スケール/サイズを制限することでクエリプランの数を減らすというあなたの考えも正しいように聞こえます。varchar文字列の場合、予想される最大値にサイズを設定できます。これは、クエリが大きなサイズ制限を持つパラメータ文字列をより小さいサイズの sと比較するときに正しく機能するはずです。小数の精度を少しだけ選ぶのも正しいように思えます。精度とスケールのペアを 1 つだけにできるかどうかを確認してください。可能かもしれません (作業中のプロジェクトでは非常にうまく機能しました)。それができれば、SQL クエリごとに 1 つのクエリ プランに進むことができます。

于 2012-01-28T16:47:43.610 に答える