Verwenden des Abfragespeicher mit IN-Memory OLTP

Gilt für:SQL ServerAzure SQL-Datenbank

MIT SQL Server Abfragespeicher können Sie die Leistung von systemeigenem kompiliertem Code für Arbeitslasten überwachen, die im Arbeitsspeicher OLTP ausgeführt werden.

Kompilier- und Laufzeitstatistiken werden auf dieselbe Weise wie bei datenträgerbasierten Arbeitsauslastungen erfasst und verfügbar gemacht. Wenn Sie zu IN-Memory OLTP migrieren, können Sie weiterhin Abfragespeicher Ansichten in SQL Server Management Studio und benutzerdefinierte Skripts verwenden, die Sie vor der Migration für datenträgerbasierte Workloads entwickelt haben. Dies spart Ihre Investition in das Lernen Abfragespeicher Technologie und macht sie für die Problembehandlung für alle Workloads nutzbar.
Allgemeine Informationen zum Verwenden des Abfragespeichers finden Sie unter Überwachen der Leistung mit dem Abfragespeicher.

Für die Verwendung der Abfragespeicher mit in-Memory-OLTP ist keine zusätzliche Featurekonfiguration erforderlich. Wenn Sie sie in Ihrer Datenbank aktivieren, funktioniert sie für alle Arten von Workloads.
Es gibt jedoch einige Aspekte, die Benutzer bei der Verwendung des Abfragespeichers mit In-Memory-OLTP beachten sollten:

  • Wenn Abfragespeicher aktiviert ist, werden Abfragen, Pläne und Kompilierungszeitstatistiken standardmäßig erfasst. Die Laufzeitstatistiksammlung wird jedoch nur aktiviert, wenn Sie sie explizit mit sys.sp_xtp_control_query_exec_stats (Transact-SQL) aktivieren.

  • Wenn Sie @new_collection_value auf 0 festlegen, beendet die Abfragespeicher das Sammeln von Laufzeitstatistiken für die betroffene Prozedur oder die gesamte SQL Server-Instanz.

  • Der mit sys.sp_xtp_control_query_exec_stats (Transact-SQL) konfigurierte Wert wird nicht beibehalten. Stellen Sie sicher, dass Sie die Statistikauflistung nach dem Neustart von SQL Server überprüfen und konfigurieren.

  • Wie bei der regulären Abfragestatistiksammlung kann sich die Leistung verringern, wenn Sie Abfragespeicher zum Nachverfolgen der Workloadausführung verwenden. Erwägen Sie die Aktivierung der Statistikauflistung nur für eine wichtige Teilmenge der nativ kompilierten gespeicherten Prozeduren.

  • Abfragen und Pläne werden auf der ersten nativen Kompilierung erfasst und gespeichert und bei jeder Neukompilierung aktualisiert.

  • Wenn Sie Abfragespeicher aktiviert oder den Inhalt gelöscht haben, nachdem alle systemeigenen gespeicherten Prozeduren kompiliert wurden, müssen Sie sie manuell kompilieren, um sie von der Abfragespeicher zu erfassen. Dies gilt auch, wenn Sie Abfragen manuell mithilfe von sp_query_store_remove_query (Transact-SQL) oder sp_query_store_remove_plan (Transact-SQL) entfernt haben. Verwenden Sie sp_recompile (Transact-SQL), um die Prozedurumkompilierung zu erzwingen.

  • Der Abfragespeicher nutzt Planerstellungsmechanismen aus In-Memory-OLTP zum Erfassen des Abfrageausführungsplans während der Kompilierung. Der gespeicherte Plan ist semantisch gleichwertig mit einem Plan, den Sie durch die Verwendung von SET SHOWPLAN_XML ON erhalten würden, bis auf einen Unterschied: Im Abfragespeicher werden Pläne geteilt und für jede einzelne Anweisung gespeichert.

  • Wenn Sie Abfragespeicher in einer Datenbank mit einer gemischten Workload ausführen, können Sie das feld is_natively_compiled aus sys.query_store_plan (Transact-SQL) verwenden, um abfragepläne schnell zu finden, die von der systemeigenen Codekompilierung generiert werden.

  • Abfragespeicher Aufnahmemodus (QUERY_CAPTURE_MODE Parameter in ALTER TABLE-Anweisung) wirkt sich nicht auf Abfragen aus nativ kompilierten Modulen aus, da sie unabhängig vom konfigurierten Wert immer erfasst werden. Dies beinhaltet das Festlegen von QUERY_CAPTURE_MODE = NONE.

  • Die Dauer der vom Abfragespeicher erfassten Abfragekompilierung umfasst nur Zeit für die Abfrageoptimierung, bevor der systemeigene Code generiert wurde. Genauer gesagt umfasst es nicht die Zeit für die C-Code-Kompilierung und -Generierung interner Datenstrukturen, die für die Generierung von C-Code erforderlich sind.

  • Speichererteilungsmetriken in sys.query_store_runtime_stats (Transact-SQL) werden für systemeigene kompilierte Abfragen nicht aufgefüllt – ihre Werte sind immer 0. Die Speicherzuweisungsspalten sind die folgenden: avg_query_max_used_memory, last_query_max_used_memory, min_query_max_used_memory, max_query_max_used_memory und stdev_query_max_used_memory.

Aktivieren und Verwenden von Abfragespeicher mit IN-Memory OLTP

Das folgende einfache Beispiel veranschaulicht die Verwendung des Abfragespeichers mit In-Memory-OLTP in einem End-to-End-Benutzerszenario. In diesem Beispiel wird davon ausgegangen, dass eine Datenbank (MemoryOLTP) für OLTP im Arbeitsspeicher aktiviert ist.
Weitere Informationen zu voraussetzungen für speicheroptimierte Tabellen finden Sie unter Erstellen einer speicheroptimierten Tabelle und einer nativ kompilierten gespeicherten Prozedur.

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

Siehe auch