一部のプロジェクトで、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 とその使用方法の問題であるためです。