Använd Query Store med In-Memory OLTP

gäller för:SQL ServerAzure SQL Database

Med SQL Server Query Store kan du övervaka prestanda för intern kompilerad kod för arbetsbelastningar som kör minnesintern OLTP.

Kompilerings- och körningsstatistik samlas in och exponeras på samma sätt som för diskbaserade arbetsbelastningar. När du migrerar till minnesintern OLTP kan du fortsätta använda Query Store-vyer i SQL Server Management Studio och anpassade skript som du har utvecklat för diskbaserade arbetsbelastningar före migreringen. Detta sparar din investering i att lära dig Query Store-teknik och gör det användbart för felsökning av alla arbetsbelastningar.
Allmän information om hur du använder Query Store finns i Övervaka prestanda med hjälp av Query Store.

Att använda Query Store med minnesintern OLTP kräver ingen ytterligare funktionskonfiguration. När du aktiverar den i databasen fungerar den för alla typer av arbetsbelastningar.
Det finns dock vissa specifika aspekter som användarna bör känna till när de använder Query Store med minnesintern OLTP:

  • När Query Store är aktiverat samlas frågor, planer och kompileringsstatistik in som standard. Insamling av körningsstatistik aktiveras dock bara om du uttryckligen aktiverar den med sys.sp_xtp_control_query_exec_stats (Transact-SQL).

  • När du anger @new_collection_value till 0 slutar Query Store att samla in körningsstatistik för den berörda proceduren eller hela SQL Server-instansen.

  • Värdet som konfigurerats med sys.sp_xtp_control_query_exec_stats (Transact-SQL) sparas inte. Kontrollera att du kontrollerar och konfigurerar statistiksamlingen igen när du har startat om SQL Server.

  • Precis som med vanlig insamling av frågestatistik kan prestandan minska när du använder Query Store för att spåra arbetsbelastningskörning. Överväg att endast aktivera statistikinsamling för en viktig delmängd av internt kompilerade lagrade procedurer.

  • Frågor och planer samlas in och lagras på den första interna kompileringen och uppdateras vid varje omkompilering.

  • Om du har aktiverat Query Store eller rensat dess innehåll efter att alla inbyggda lagrade procedurer kompilerats måste du kompilera om dem manuellt för att få dem att hämtas av Query Store. Detsamma gäller om du tog bort frågor manuellt med hjälp av sp_query_store_remove_query (Transact-SQL) eller sp_query_store_remove_plan (Transact-SQL). Använd sp_recompile (Transact-SQL) för att framtvinga omkompilering av procedurer.

  • Query Store använder mekanismer för plangenerering från minnesintern OLTP för att samla in frågekörningsplanen under kompilering. Lagrade planer är semantiskt likvärdiga med de som du skulle få genom att använda SET SHOWPLAN_XML ON med en skillnad; planer i Query Store delas upp och lagras per enskilt uttryck.

  • När du kör Query Store i en databas med en blandad arbetsbelastning kan du använda fältet is_natively_compiled från sys.query_store_plan (Transact-SQL) för att snabbt hitta frågeplaner som genereras av den interna kodkompilering.

  • Avbildningsläget för Query Store (QUERY_CAPTURE_MODE parameter i ALTER TABLE-instruktionen ) påverkar inte frågor från inbyggda kompilerade moduler eftersom de alltid registreras oavsett det konfigurerade värdet. Detta inkluderar inställningen QUERY_CAPTURE_MODE = NONE.

  • Varaktigheten för frågekompilering som samlas in av Query Store omfattar endast tid som ägnas åt frågeoptimering innan den interna koden genererades. Mer exakt inkluderar det inte tid för C-kodkompilering och generering av interna strukturer som krävs för C-kodgenerering.

  • Minnesbeviljanden inom sys.query_store_runtime_stats (Transact-SQL) fylls inte i för nativt kompilerade frågor – deras värden är alltid 0. Kolumnerna för minnestilldelar är: avg_query_max_used_memory, last_query_max_used_memory, min_query_max_used_memory, max_query_max_used_memory och stdev_query_max_used_memory.

Aktivera och använda Query Store med In-Memory OLTP

Följande enkla exempel demonstrerar användningen av Query Store med minnesintern OLTP i ett heltäckande användarscenario. I det här exemplet förutsätter vi att en databas (MemoryOLTP) är aktiverad för minnesintern OLTP.
Mer information om förutsättningar för minnesoptimerade tabeller finns i Skapa en Memory-Optimized-tabell och en intern kompilerad lagrad procedur.

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');

Se även