web-dev-qa-db-ja.com

SQL Server 2008R2のAUTO_UPDATE_STATISTICSおよびFULLSCAN

SQL Server 2008 R2によって統計が更新されたときにFULLSCANを強制することは可能ですか自動的に

そうでない場合は、計画されていますUPDATE STATISTICS WITH FULLSCAN統計を最新に保つための最良の方法は?

注:FULLSCANの必要性は、非FULLSCAN統計を使用する場合に証明された次善の計画生成によってもたらされます。

3
CAFxX

自動更新では常にサンプリングが使用され、パーセンテージはインデックスの行数から計算されます。

あなたから SO投稿

 Just FYI, the two indexes were PKs of tables having 280M+ and 55M+ rows, respectively.

これは、SQLServerがFULLSCAN自動更新を許可しない理由の良い例だと思います。その数の行計画外を読み取ることの影響は、解決するのと同じくらい多くの頭痛の種を引き起こす可能性があります。

2つのオプション:

  • 自動更新を無効にして、フルスキャンをスケジュールします。
  • 統計が100%正確であることに依存せずに、クエリオプティマイザーをナッジ/ヒント/スレッジハンマーで優先プランを使用します。

John Sansomは、あなたのSOの投稿に対するコメントで、あなたを2番目のルートに導こうとしていました。あなたの回答は、あなたがそのアイデアに熱心ではないことを示唆していますか?

それが実際の質問と何の関係があるのか​​実際にはわかりません...とにかく、次善の計画では2つのクラスター化インデックススキャンが使用されましたが、最適なプランでは存在しません(同じインデックスのシークに置き換えられました)。

統計を最新の状態に保ち、適切な実行プランを維持するのに十分な頻度でフルスキャンを実行できない場合は、他のオプションがあります。問題実行計画に関する適切な情報があれば、適切なオプションを提案できます。開始するためのいくつかの提案:

昇順のキーと自動クイック修正統計 -大きなテーブルでの珍しい統計の問題は、たとえば昇順のデータ、日付、ID列です。最後の統計更新後に作成されたデータのフィルターにより、実際には多数の行が存在する場合に、実行プランで非常に低い選択性が期待される可能性があります。

ヒント および/または プランガイド --OPTIMIZE FORおよびRECOMPILEはシナリオに適用できる場合があります。 KEEPFIXED PLANは、スケジュールされた統計更新の直後に再コンパイルを強制することと組み合わせて使用​​できます。

Plan Forcing -適切な計画をキャプチャし、問題クエリに添付します。

編集:これがベンダーアプリケーションであることに関する次のコメントを更新します

これがまさにプランガイドが存在する理由であり、ソースコードを変更できない場合にDBAが実行プランに影響を与える機会を与えます。 2つのアプローチがあります(両方のコードサンプルはBOLから取得されました)。

  • プランガイドの理解 で概説されているように、オブジェクト(ターゲットがストアドプロシージャの場合)またはSQLプラン(単一のステートメントに一致する場合)ガイドを作成し、OPTIONヒントを適用するか、キャプチャによって適切な実行プランを添付します。
USE AdventureWorks2008R2;
GO
SELECT City, StateProvinceID, PostalCode FROM Person.Address ORDER BY PostalCode DESC;
GO
DECLARE @xml_showplan nvarchar(max);
SET @xml_showplan = (SELECT query_plan
    FROM sys.dm_exec_query_stats AS qs 
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st
    CROSS APPLY sys.dm_exec_text_query_plan(qs.plan_handle, DEFAULT, DEFAULT) AS qp
    WHERE st.text LIKE N'SELECT City, StateProvinceID, PostalCode FROM Person.Address ORDER BY PostalCode DESC;%');

EXEC sp_create_plan_guide 
    @name = N'Guide1_from_XML_showplan', 
    @stmt = N'SELECT City, StateProvinceID, PostalCode FROM Person.Address ORDER BY PostalCode DESC;', 
    @type = N'SQL',
    @module_or_batch = NULL, 
    @params = NULL, 
    @hints = @xml_showplan;
GO
USE AdventureWorks2008R2;
GO
SELECT WorkOrderID, p.Name, OrderQty, DueDate
FROM Production.WorkOrder AS w 
JOIN Production.Product AS p ON w.ProductID = p.ProductID
WHERE p.ProductSubcategoryID > 4
ORDER BY p.Name, DueDate;
GO
-- Inspect the query plan by using dynamic management views.
SELECT * FROM sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(sql_handle)
CROSS APPLY sys.dm_exec_text_query_plan(qs.plan_handle, qs.statement_start_offset, qs.statement_end_offset) AS qp
WHERE text LIKE N'SELECT WorkOrderID, p.Name, OrderQty, DueDate%';
GO
-- Create a plan guide for the query by specifying the query plan in the plan cache.
DECLARE @plan_handle varbinary(64);
DECLARE @offset int;
SELECT @plan_handle = plan_handle, @offset = qs.statement_start_offset
FROM sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS st
CROSS APPLY sys.dm_exec_text_query_plan(qs.plan_handle, qs.statement_start_offset, qs.statement_end_offset) AS qp
WHERE text LIKE N'SELECT WorkOrderID, p.Name, OrderQty, DueDate%';

EXECUTE sp_create_plan_guide_from_handle 
    @name =  N'Guide1',
    @plan_handle = @plan_handle,
    @statement_start_offset = @offset;
GO
-- Verify that the plan guide is created.
SELECT * FROM sys.plan_guides
WHERE scope_batch LIKE N'SELECT WorkOrderID, p.Name, OrderQty, DueDate%';
GO
5

統計の更新を強制する非常に率直な方法...

統計情報を更新するだけで、フルスキャンはおそらく必要ないかもしれません。これで、自動更新をトリガーするのに十分なデータ変更がある場合は、おそらく論理的な断片化もあります。

使用されている問題のあるテーブル/インデックスに対して、1時間ごとにオンラインインデックスビルドを実行してみます

ALTER INDEX ALL ON ... WITH (ONLINE = ON)

注:列の統計は、インデックスの再構築では更新されません。しかし、それらが必要な場合は、インデックスが必要です。

0
gbn