私のアプリケーションは、SQL Serverデータベースに対してクエリを実行します。
多くの場合、実行計画の利点がわかります。たとえば、ボタンをクリックして初めて
SELECT * from Tasks
WHERE IdUser = 24 AND
DATE < "12/12/2010" and DATE > "01/01/2010"
最初の時間は15秒、次の時間は8秒かかります。
編集:私はパラメータを使用します。
だから私は2回目に7秒間の改善があります。
今度はアプリケーションをもう一度実行すると(新しいデータベース接続を行うため)、初めて15秒、2回目に7回...
SQL Serverに格納する方法を教えてください実行計画は、少なくとも同じ日にそれらを覚えていますか?あるいは、すでに計算された実行計画の利点をどのように得ることができますか?異なるユーザーが同じクエリを実行する場合は、同じ実行計画を使用するのに十分なほどスマートになるようにSQL Serverに指示する方法です。その場合でもおそらくIdUserは異なります。
私はいくつかのパラメータを持っているので、次回のクエリの実行には異なるMinDateとMaxDateがありますが、これはクエリプランに影響しますか?
回答:
回答№1は2パラメータ化されたクエリを使用して、プランがキャッシュされる機会を最大限に活用する
SELECT * from MYTasks
WHERE IdUser = @UserId AND DATE < @enddate and DATE > @startdate
SQL Serverは自動パラメータ化を行いますが、これについてはかなり保守的です。
プランの再利用については、以下から洞察を得ることができます
SELECT usecounts, cacheobjtype, objtype, text, query_plan, value as set_options
FROM sys.dm_exec_cached_plans
CROSS APPLY sys.dm_exec_sql_text(plan_handle)
CROSS APPLY sys.dm_exec_query_plan(plan_handle)
cross APPLY sys.dm_exec_plan_attributes(plan_handle) AS epa
where text like "%MYTasks%" and attribute="set_options"
回答№2については2
SQL Serverはこれを行います。使用可能なスペースがある限り、実行プランはすべて格納されます。
しかし、実行計画を保存して再利用する機会を増やすために、多くのことを行うことができます。必要なのは、作成することです 同一 SQLクエリ - 余分なスペースがあれば、SQL Serverは2つのクエリを異なるものとみなし、既存のクエリプランを再利用しないことがあります。
したがって、
あなたのクエリで一貫している - 常に同じように物事を綴る(大文字/小文字の区別、空白、
dbo.
プレフィックスなど)リテラル値の代わりにパラメータを使用する。リテラル値を使用すると、クエリプランが再利用されず、不必要にプランキャッシュがいっぱいになります。
避けようとする
SELECT *
- これは、クエリオプティマイザのオプションが少ないことを意味します - すべての列が必要なため、通常はクラスタード・インデックスでスキャンを実行する必要があります。本当に必要な3,5,6列を指定すると、クエリを扱うインデックスが存在する可能性があります(関心のあるすべての列が含まれているため)、クエリ分析でそのインデックスを使用してそれに対する索引スキャン/索引探索(およびその計画の再利用)。
だからあなたのSQLの代わりに、代わりにこれを使う:
SELECT (list of fields)
FROM dbo.MYTasks
WHERE DATE < @EndDate and DATE > @StartDate
これにより、クエリプランの再利用が大幅に増加するはずです。
回答№3の場合は0
SQL Server Profilerを実行しましたか?もしそうなら、ステートメントのコンパイルと実行計画の生成に余分な時間がかかるのでしょうか?
問題の説明から、追加の7秒はデータベースへの初期接続をセットアップする時間になります。たぶんあなたはすでにこれを否定しています。私は知りません。
さらに懸念されるのはデータキャッシュです。初めてデータにアクセスすると、SQL Serverはそのデータをキャッシュにロードします。これにより、後続のクエリの時間を短縮できます(すべてのデータを保持できると仮定します)。