インメモリ OLTP でのクエリ ストアの使用
適用対象: SQL Server Azure SQL データベース
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');