web-dev-qa-db-ja.com

間違った最終実行時間sys.dm_exec_procedure_stats

次のクエリを実行しています。これは、2016年6月6日月曜日の午前8時45分に実行されたことがわかっている保存済みプロシージャを示していますが、以下のクエリは、最後の実行時間が2016-05-19 12:09:23.197であることを示しています。ここに欠けているものがありますか、それともサーバーの問題ですか?私がオンラインで見つけたものはすべて、procが実行されていないのに実行されているというレポートを人々が受け取るという反対の問題を指します。

SELECT * FROM sys.dm_exec_procedure_stats AS s
INNER JOIN sys.procedures AS p
ON s.[object_id] = p.[object_id]
2
scripter78

主要な問題は、同じobject_idを持つ2つの異なるデータベース内の2つの異なるプロシージャでクエリが一致する可能性があることです。オンデマンドでそれを再現する信頼できる方法はありませんが、それが一般的であり、クエリがそれから保護する必要があることを知るのに十分な回数を見てきました。 WHERE句を使用してこれを行うことができます。

WHERE s.database_id = DB_ID();

other データベースの統計を取得する場合は、次を使用できます。

...
FROM sys.dm_exec_procedure_stats AS s
INNER JOIN [other_database].sys.procedures AS p
ON s.[object_id] = p.[object_id]
WHERE s.[database_id] = DB_ID(N'other_database');

注1:統計DMVは、サービスの再起動、フェイルオーバー、またはプロシージャキャッシュをフラッシュするアクション(たとえば、データベース用、または特定の手順用)。また、意図的にキャッシュされていないストアドプロシージャのエントリはDMVに表示されません。 EXEC dbo.procedurename WITH RECOMPILE;。したがって、手順AがDMVに存在しないという理由だけで、手順Aが使用されていないと結論付けることは必ずしも信頼できるとは限りません。

注2fooという名前のデータベースがその存続期間にわたって異なるdatabase_id値を持つ可能性があります(次の場合を考慮してください)。 fooを削除し、別のデータベースを作成してから、fooの別のインスタンスを作成します。これはありそうにありませんが、fooの古いコピーで発生したストアドプロシージャの実行を見逃す可能性があるため、言及する価値があります。

注3:未使用の一連のプロシージャを実際に測定して決定する場合は、監査/拡張イベント/サーバーなどの重い方法を使用する必要があります。 -サイドトレース、またはこのヒントで説明するように、ストアドプロシージャに手動でログを追加します。

それでも、たとえば四半期または他の会計期間に1回だけ実行されるレポートを見逃さないように、ビジネスサイクル全体にわたって実行を続ける必要があります。

think が使用されていないストアドプロシージャのセットを特定したら、それらを削除しないでください。それらを別のスキーマに配置します(ここではzzzを使用しているため、オブジェクトエクスプローラーのリストの一番下で並べ替えられますが、名前は重要ではありません。ユーザーの誰もがデフォルトとして設定していないことを確認してください。スキーマ、そして多分DENY EXECUTEを実装することさえあります)。

CREATE SCHEMA zzz;
GO
ALTER SCHEMA zzz TRANSFER dbo.UnusedProcedureName1;
ALTER SCHEMA zzz TRANSFER dbo.UnusedProcedureName2;
...

これは、プロシージャを削除するほど効果的に混乱を軽減するわけではありませんが、非常に低コストの保険契約のようなものであり(データファイルとバックアップにストアドプロシージャテキストを保存するだけです)、復元が非常に簡単になります。エラーで未使用と見なされた手順。

4
Aaron Bertrand