Verwenden Sie den Abfragespeicher mit In-Memory OLTP

Gilt für:SQL ServerAzure SQL-Datenbank

SQL Server-Abfragespeicher ermöglicht es Ihnen, die Leistung nativ kompilierter Codes für In-Memory-OLTP-Arbeitsauslastungen zu überwachen.

Kompilier- und Laufzeitstatistiken werden auf dieselbe Weise wie bei datenträgerbasierten Arbeitsauslastungen erfasst und verfügbar gemacht. Bei der Migration zu In-Memory-OLTP können Sie weiterhin Abfragespeichersichten in SQL Server Management Studio und benutzerdefinierte Skripts verwenden, die Sie vor der Migration für datenträgerbasierte Arbeitsauslastungen entwickelt haben. Dadurch bleibt Ihre Investition in das Erlernen der Abfragespeicher-Technologie erhalten und kann für die Problembehandlung bei allen Workloads genutzt werden.
Allgemeine Informationen zum Verwenden des Abfragespeichers finden Sie unter Überwachen der Leistung mit dem Abfragespeicher.

Das Verwenden des Abfragespeichers mit In-Memory-OLTP erfordert keine weitere Funktionskonfiguration. Wenn Sie ihn auf Ihrer Datenbank aktivieren, funktioniert er für alle Arbeitsauslastungstypen.
Es gibt jedoch einige Aspekte, die Benutzer bei der Verwendung des Abfragespeichers mit In-Memory-OLTP beachten sollten:

  • Wenn der Abfragespeicher aktiviert ist, werden Abfragen, Pläne und Kompilierzeitstatistiken standardmäßig erfasst. Die Erfassung von Laufzeitstatistiken ist nur aktiviert, wenn Sie diese explizit mit sys.sp_xtp_control_query_exec_stats (Transact-SQL) aktivieren.

  • Wenn Sie @new_collection_value auf 0 festlegen, erfasst der Abfragespeicher keine Laufzeitstatistiken mehr für die betroffene Prozedur oder für die gesamte SQL Server-Instanz.

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

  • Wie bei der Erfassung regulärer Abfragestatistiken kann sich die Leistung verringern, wenn Sie Abfragespeicher verwenden, um die Workloadausführung nachzuverfolgen. Ziehen Sie in Betracht, die Statistikerfassung nur für eine wichtige Teilmenge nativ kompilierter gespeicherter Prozeduren zu aktivieren.

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

  • Wenn Sie den Abfragespeicher aktiviert oder dessen Inhalt gelöscht haben, nachdem alle nativen gespeicherten Prozeduren kompiliert wurden, müssen Sie diese manuell erneut kompilieren, damit sie vom Abfragespeicher erfasst werden. Das Gleiche gilt, wenn Sie Abfragen manuell mit 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 Neukompilierung der Prozedur zu erzwingen.

  • Abfragespeicher nutzt die Planerstellungsmechanismen von In-Memory-OLTP, um den Abfrageausführungsplan bei der Kompilierung zu erfassen. Der gespeicherte Plan ist semantisch äquivalent zu dem Plan, den Sie bei Verwendung von SET SHOWPLAN_XML ON erhalten würden, mit einem Unterschied: Im Abfragespeicher werden Pläne nach einzelnen Anweisungen getrennt und gespeichert.

  • Wenn Sie den Abfragespeicher in einer Datenbank mit gemischten Arbeitsauslastungen ausführen, können Sie von der nativen Kompilierung des Codes generierte Abfragepläne mithilfe des Felds is_natively_compiled in sys.query_store_plan (Transact-SQL)schnell finden.

  • 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 durch den Abfragespeicher erfasste Dauer der Abfragekompilierung enthält nur die Zeit, die für die Optimierung von Abfragen vor dem Generieren des nativen Codes verwendet 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.

  • Speicherzuweisungsmetriken in sys.query_store_runtime_stats (Transact-SQL) werden für nativ kompilierte Abfragen nicht aufgefüllt. Ihre Werte sind immer 0 (null). Die Spalten für Speicherzuweisungen sind: 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 des 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 für In-Memory-OLTP eine Datenbank (MemoryOLTP) aktiviert ist.
Weitere Informationen zu den 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