2

質問:

DateTime.Nowパラメータとして proc に渡すと、SQL Server がクエリ プランをキャッシュできなくなりますか? もしそうなら、ウェブアプリは大幅なパフォーマンスの向上を逃していますか?

考えられる解決策:

DateTime.Today.AddDays(1)可能な解決策になると思いました。同じ終了日を sql proc に渡します (1 日あたり)。また、ユーザーは引き続き最新のデータを取得できます。こちらもご相談ください。

与えられた例:

ストアド プロシージャがあるとします。Web ページでユーザーにデータを報告します。ユーザーは日付範囲を設定できます。ユーザーが今日のデータを含む「終了日」として今日の日付を設定すると、Web アプリDateTime.Nowは sql プロシージャに渡します。

1 人のユーザーがレポートを何度も実行する5/1/2010nowします。Web ページで、ユーザーには が表示5/1/2010され5/4/2010ます。ただし、Web アプリDateTime.Nowは終了日として sql proc に渡します。そのため、ユーザーが同様の日付範囲を照会していても、proc の終了日は常に異なります。

テーブル内のレコード数とユーザー数が多いとします。したがって、パフォーマンスの向上は重要です。したがって、質問の重要性。

proc と実行の例 (理解に役立つ場合):

CREATE PROCEDURE GetFooData
    @StartDate datetime
    @EndDate datetime
AS

    SELECT *
    FROM Foo
    WHERE LogDate >= @StartDate
    AND LogDate < @EndDate

DateTime.Now を使用した実行例を次に示します。

EXEC GetFooData '2010-05-01', '2010-05-04 15:41:27' -- passed in DateTime.Now

DateTime.Today.AddDays(1) を使用した実行例を次に示します。

EXEC GetFooData '2010-05-01', '2010-05-05' -- passed in DateTime.Today.AddDays(1)

現在の時刻が であるため、両方の proc に対して同じデータが返されます2010-05-04 15:41:27

4

3 に答える 3

6

クエリ プランは、パラメーター値に関係なくキャッシュされます。パラメータは基本的に、SQL サーバーに関する限りタイプセーフであるため、一貫性のある再利用可能なクエリが存在することを保証します。

必要なのは、クエリ プランではなく、結果のキャッシュです。そして、これはあなたが説明する行動の影響を受けます。

丸一日のみを処理しているように見えるため、日時ではなく日付を渡して、さまざまなパラメーター値を最小限に抑えることができます。また、毎回データベースを往復するのではなく、クエリ結果をアプリケーションにキャッシュしてみてください。

于 2010-05-04T22:50:39.740 に答える
1

クエリを直接呼び出すのではなく、ストアドプロシージャを呼び出すため、変更されるクエリは、SQLに送信する実際のバッチとEXEC GetFooData '2010-05-01', '2010-05-05'vs.だけGetFooData '2010-05-01', '2010-05-04 15:41:27'です。これは些細なバッチであり、些細な計画を生成します。確かに、厳密な技術的観点からは、パフォーマンスがいくらか失われていますが、それはほとんど測定不可能です。この問題がこの応答で説明されている理由の詳細:SQLServerで動的に作成されたSQLとパラメーター

幸いなことに、SqlClient呼び出しコードを少し変更するだけで、そこに記載されているパフォーマンスのわずかな改善からも恩恵を受けることができます。SqlCommandコードを、明示的なストアドプロシージャ呼び出しになるように変更します。

SqlCommand cmd = new SqlCommand("GetFooData", connection);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@StartDate", dateFrom);
cmd.Parameters.AddWithValue("@EndDate", DateTime.Now);

ちなみに、ローカライズされた時刻をデータベースに保存することは、クライアントがサーバーとは異なるタイムゾーンにあり、夏時間の複雑さのために、あまり良い考えではありません。はるかに優れた解決策は、常にUTC時刻を保存し、アプリケーションでユーザーの現地時間にフォーマットすることです。

于 2010-05-05T01:18:52.063 に答える
1

あなたの場合、2 番目のパラメーターがリアルタイムで上向きにドリフトしている場合は、おそらく問題ありません。

ただし、最初の実行 (キャッシュされた実行プランを生成する) が、通常使用される他のパラメーターにとって通常適切ではないプランを生成するパラメーターを使用して呼び出される (またはデータ プロファイルが大幅に変更される) 場合、パラメーター スニッフィングの被害者になる可能性があります。 )。後の呼び出しでは、適切に完了さえしないほど貧弱な計画が使用される場合があります。

パラメータの選択によってデータ プロファイルが大幅に変化し、特定のパラメータの選択に対して実行計画が不十分になる場合は、パラメータをローカル変数にマスクすることができます。これにより、SQL Server 2005 でのパラメータ スニッフィングを効果的に防ぐことができます。WITH RECOMPILE もあります。 (SPまたはEXECのいずれか-ただし、頻繁に呼び出されるSPの場合、これは実行可能なオプションではありません)SQL Server 2008では、ほとんどの場合、パラメータースニッフィングに基づく計画の作成を回避するOPTIMIZE FOR UNKNOWNを使用します。

于 2010-05-05T03:52:16.303 に答える