Поделиться через


Использование хранилище запросов с OLTP в памяти

Область применения: SQL Server База данных SQL Azure

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 (Transact-SQL). Используйте sp_recompile (Transact-SQL) для принудительной перекомпиляции процедуры.

  • Хранилище запросов использует механизмы создания планов из выполняющейся в памяти OLTP, чтобы записать план выполнения запроса в процессе компиляции. Хранимый план семантически эквивалентен плану, получаемому с использованием SET SHOWPLAN_XML ON , но с одним отличием: планы в хранилище запросов разбиваются и хранятся по каждой отдельной инструкции.

  • При запуске хранилище запросов в базе данных с смешанной рабочей нагрузкой можно использовать поле is_natively_compiled из sys.query_store_plan (Transact-SQL) для быстрого поиска планов запросов, создаваемых компиляцией машинного кода.

  • хранилище запросов режим записи (параметр QUERY_CAPTURE_MODE в инструкции ALTER TABLE) не влияет на запросы из скомпилированных модулей, так как они всегда фиксируются независимо от настроенного значения. Это включает настройку 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 в сквозном пользовательском сценарии. В этом примере предполагается, что база данных (MemoryOLTP) включена для OLTP в памяти.
Дополнительные сведения о предварительных требованиях для оптимизированных для памяти таблиц см. в разделе "Создание оптимизированной для памяти таблицы" и скомпилированной хранимой процедуры.

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

См. также