インメモリ OLTP でのクエリ ストアの使用

適用対象:SQL ServerAzure SQL Database

SQL Server クエリ ストアを利用することで、インメモリ OLTP で実行されているワークロードについて、ネイティブ コンパイル コードのパフォーマンスを監視する方法について説明します。

コンパイルと実行時の統計情報が収集され、ディスク ベースのワークロードと同じように公開されます。 インメモリ OLTP に移行しても、SQL Server Management Studio で引き続きクエリ ストア ビューを使用でき、移行前にディスク ベースのワークロード用に開発したカスタム スクリプトを使用できます。 これにより、クエリ ストア テクノロジを学習するための出資を節約し、これをすべてのワークロードのトラブルシューティングで使用できるようになります。
クエリ ストアの使用に関する一般情報については、「 Monitoring Performance By Using the Query Store」を参照してください。

インメモリ OLTP でクエリ ストアを使用する場合、追加の機能構成は必要ありません。 データベースで有効にすれば、すべての種類のワークロードで機能します。
ただし、ユーザーがインメモリ OLTP でクエリ ストアを使用する際に注意する必要がある点がいくつかあります。

  • クエリ ストアを有効にすると、クエリ、プランおよびコンパイル時の統計が既定で収集されます。 ただし、ランタイム統計の収集は、sys.sp_xtp_control_query_exec_stats (Transact-SQL) で明示的に有効にした場合のみアクティブになります。

  • @new_collection_value を 0 に設定すると、クエリ ストアは影響を受けるプロシージャまたは SQL Server インスタンス全体のランタイム統計の収集を停止します。

  • sys.sp_xtp_control_query_exec_stats (Transact-SQL) で構成された値は保持されません。 SQL Server の再起動後に、統計収集を確認し、再構成するようにしてください。

  • 通常のクエリの統計収集の場合と同じように、クエリ ストアを使用してワークロードの実行を追跡する際にパフォーマンスが低下する可能性があります。 ネイティブ コンパイル ストアド プロシージャの重要なサブセットに対してのみ、統計収集を有効にすることを検討してください。

  • クエリとプランは最初のネイティブ コンパイルでキャプチャおよび格納され、再コンパイルのたびに更新されます。

  • すべてのネイティブ ストアド プロシージャがコンパイルされてからクエリ ストアを有効にしたか、その内容をクリアした場合は、手動で再コンパイルして、クエリ ストアでキャプチャされるようにする必要があります。 sp_query_store_remove_query (Transact-SQL) または sp_query_store_remove_plan (Transct-SQL) を使用して手動でクエリを削除した場合も同様です。 sp_recompile (Transact-SQL) を使用して、プロシージャを強制的に再コンパイルしてください。

  • クエリ ストアではインメモリ OLTP のプラン生成メカニズムを活用して、コンパイル時にクエリ実行プランをキャプチャします。 ストアド プランは、 SET SHOWPLAN_XML ON を使用して取得するものと意味的には同じです。ただし、クエリ ストアのプランはステートメントごとに分割され、格納されます。

  • 混合ワークロードのデータベースでクエリ ストアを実行する場合は、sys.query_store_plan (Transact-SQL)is_natively_compiled フィールドを使用して、ネイティブ コード コンパイルで生成されたクエリ プランをすばやく見つけることができます。

  • クエリ ストアのキャプチャ モード (ALTER TABLE ステートメントの QUERY_CAPTURE_MODE パラメーター) が、ネイティブ コンパイル モジュールからのクエリに影響することはありません。これらは構成値に関係なく、常にキャプチャされます。 これには QUERY_CAPTURE_MODE = NONEの設定も含まれます。

  • クエリ ストアでキャプチャされるクエリ コンパイルの期間には、ネイティブ コードが生成される前にクエリ最適化に要した時間のみが含まれます。 もっと正確に言うと、C コードのコンパイルおよび C コードの生成に必要な内部構造の生成に要した時間は含まれません。

  • sys.query_store_runtime_stats (Transact-SQL) 内のメモリ許可メトリックは、ネイティブ コンパイル クエリでは設定されません。この値は常に 0 です。 メモリの許可の列は、avg_query_max_used_memory、last_query_max_used_memory、min_query_max_used_memory、max_query_max_used_memory、および stdev_query_max_used_memory です。

インメモリ OLTP でのクエリ ストアの有効化および使用

エンド ツー エンド ユーザー シナリオでのクエリ ストアとインメモリ OLTP の簡単な使用例を以下に示します。 この例は、インメモリ OLTP に対してデータベース (MemoryOLTP) が有効になっていることを前提としています。
メモリ最適化テーブルの前提条件についての詳細は、「メモリ最適化テーブルおよびネイティブ コンパイル ストアド プロシージャの作成」を参照してください。

USE MemoryOLTP;
GO

-- Create a simple memory-optimized table
CREATE TABLE dbo.Ord
   (OrdNo INTEGER not null PRIMARY KEY NONCLUSTERED,
    OrdDate DATETIME not null,
    CustCode NVARCHAR(5) not null)
WITH (MEMORY_OPTIMIZED=ON);
GO

-- Enable Query Store before native module compilation
ALTER DATABASE MemoryOLTP SET QUERY_STORE = ON;
GO

-- Create natively compiled stored procedure
CREATE PROCEDURE dbo.OrderInsert(@OrdNo integer, @CustCode nvarchar(5))
WITH NATIVE_COMPILATION, SCHEMABINDING
AS
    BEGIN ATOMIC WITH
    (TRANSACTION ISOLATION LEVEL = SNAPSHOT,
    LANGUAGE = N'English')

    DECLARE @OrdDate DATETIME = GETDATE();
    INSERT INTO dbo.Ord (OrdNo, CustCode, OrdDate)
        VALUES (@OrdNo, @CustCode, @OrdDate);
END;
GO

-- Enable runtime stats collection for queries from dbo.OrderInsert stored procedure
DECLARE @db_id INT = DB_ID()
DECLARE @proc_id INT = OBJECT_ID('dbo.OrderInsert');
DECLARE @collection_enabled BIT;

EXEC [sys].[sp_xtp_control_query_exec_stats] @new_collection_value = 1,
    @database_id = @db_id, @xtp_object_id = @proc_id;

-- Check the state of the collection flag
EXEC sp_xtp_control_query_exec_stats @database_id = @db_id,
    @xtp_object_id = @proc_id,
    @old_collection_value= @collection_enabled output;
SELECT @collection_enabled AS 'collection status';

-- Execute natively compiled workload
EXEC dbo.OrderInsert 1, 'A';
EXEC dbo.OrderInsert 2, 'B';
EXEC dbo.OrderInsert 3, 'C';
EXEC dbo.OrderInsert 4, 'D';
EXEC dbo.OrderInsert 5, 'E';

-- Check Query Store Data
-- Compile time data
SELECT q.query_id, plan_id, object_id, query_hash, p.query_plan,
    p.initial_compile_start_time, p.last_compile_start_time,
    p.last_execution_time, p.avg_compile_duration,
    p.last_force_failure_reason, p.force_failure_count
FROM sys.query_store_query AS q
JOIN sys.query_store_plan AS p
    ON q.query_id = p.plan_id
WHERE q.object_id = OBJECT_ID('dbo.OrderInsert');

-- Get runtime stats
-- Check count_executions field to verify that runtime statistics
-- have been collected by the Query Store
SELECT q.query_id, p.plan_id, object_id, rsi.start_time, rsi.end_time,
    p.last_force_failure_reason, p.force_failure_count, rs.*
FROM sys.query_store_query AS q
JOIN sys.query_store_plan AS p
    ON q.query_id = p.plan_id
JOIN sys.query_store_runtime_stats AS rs
    ON rs.plan_id = p.plan_id
JOIN sys.query_store_runtime_stats_interval AS rsi
    ON rs.runtime_stats_interval_id = rsi.runtime_stats_interval_id
WHERE q.object_id = OBJECT_ID('dbo.OrderInsert');

関連項目