KB4013877 - 更新啟用 DML 查詢計劃在 SQL Server 2016 中同時掃描查詢記憶體最佳化資料表

套用到
SQL Server 2016 Enterprise Core - duplicate (do not use) SQL Server 2016 Enterprise - duplicate (do not use) SQL Server 2016 Developer - duplicate (do not use) SQL Server 2016 Standard - duplicate (do not use) SQL Server 2016 Service Pack 1

摘要

在此更新之前,參照記憶體最佳化資料表或資料表變數的 DML 作業不支援平行查詢計劃,即使它們不是 DML 作業的目標。 如果有任何記憶體最佳化資料表或資料表變數的參照,INSERT、UPDATE、DELETE 及 MERGE 陳述式一律會有序列計劃,即使是傳統磁碟型資料表和資料表變數支援平行計劃的情況也一樣。

此更新在參照記憶體最佳化資料表或資料表變數的 DML 作業中,新增對記憶體最佳化資料表和資料表變數的平行計畫及平行掃描支援,只要這些資料表或資料表變數不是 DML 作業的目標即可。 INSERT、UPDATE、DELETE 及 MERGE 陳述式只要涉及修改記憶體最佳化資料表或資料表變數,則會繼續是序列式的。

以下是為參照記憶體最佳化資料表或資料表變數的 DML 陳述式啟用平行計劃的三個需求:

  1. 請確定資料庫使用相容性層級 130。 這是具有記憶體最佳化資料表的平行計畫的必要條件。

  2. 安裝包含此修正程式的服務更新。 請參閱「詳細資訊」章節。

  3. 請透過下列兩種方式之一啟用此更新:

    1. 開啟追蹤旗標 9939 以僅啟用此更新。 建議所有使用記憶體最佳化資料表或資料表變數,以及尚未使用下方選項 3b 的客戶使用此選項。
    2. 啟用 SQL Server 查詢最佳化工具 Hotfix。 您可以透過追蹤旗標 4199、資料庫範圍的設定或查詢提示來執行此動作。 如需詳細資訊,請參閱 SQLServer 查詢最佳化工具 Hotfix 追蹤旗標 4199 服務模型。

解決方式

此問題已在下列 SQL Server 累積更新中修正:

SQL Server 2016 的累積更新 5

SQL Server 2016 SP1 累積更新 3

關於 SQL Server 的累積更新:

SQL Server 的每個新累積更新都包含所有 Hotfix 和先前累積更新的所有安全性修正程式。 查看 SQL Server 的最新累積更新:

適用於 SQL Server 2016 的最新累積更新

附錄:修正範例

下列 Transact-SQL 指令碼說明在參考記憶體最佳化資料表的磁碟型資料表上執行 DML 作業的平行計劃。 套用此更新後,指令碼會針對相同的作業傳回兩個查詢計劃。 第一個是無痕標誌 9939,並且將是序列的。 第二個是啟用追蹤旗標 9939,並且會平行處理。


-- make sure that you connect to a database that has a memory-optimized filegroup with at least one container
-- the following script creates such a filegroup and container if it does not exist:
--   https://raw.githubusercontent.com/Microsoft/sql-server-samples/master/samples/features/in-memory/t-sql-scripts/enable-in-memory-oltp.sql
 
-- make sure DB compat level 130 is used
ALTER DATABASE CURRENT SET COMPATIBILITY_LEVEL=130
GO
 
DROP PROCEDURE IF EXISTS dbo.[InsertSalesOrder_Native_Batch]
DROP TABLE IF EXISTS dbo.SalesOrder_MemOpt
GO
CREATE TABLE dbo.SalesOrder_MemOpt (
    order_id     INT      IDENTITY NOT NULL,
    order_date   DATETIME NOT NULL,
    order_status TINYINT  NOT NULL,
    amount       FLOAT    NOT NULL,
    CONSTRAINT PK_SalesOrderID PRIMARY KEY NONCLUSTERED HASH (order_id) WITH (BUCKET_COUNT = 10000)
)
WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_ONLY);
GO
 
-- Natively compiled proc
-- Create Natively compiled procedure to speed up inserts.
CREATE PROCEDURE [dbo].[InsertSalesOrder_Native_Batch]
@order_status TINYINT=1, @amount FLOAT=100, @OrderNum INT=100
WITH NATIVE_COMPILATION, SCHEMABINDING, EXECUTE AS OWNER
AS
BEGIN ATOMIC
WITH (TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = 'us_english')
    DECLARE @counter AS INT = 1;
    WHILE @counter <= @OrderNum
        BEGIN
            INSERT  INTO dbo.SalesOrder_MemOpt
            VALUES (getdate(), @order_status, @amount);
            SET @counter = @counter + 1;
        END
END;
GO
-- Insert sample data
EXECUTE dbo.[InsertSalesOrder_Native_Batch] 1, 100, 500000;
GO 10
 
 
SET SHOWPLAN_XML ON
GO
 
-- Insert into a temp table from memory-optimized table
-- Without the trace flag, this is serial. Inspect the query plan to verify it is serial.
SELECT * INTO #temp FROM SalesOrder_MemOpt
GO
SET SHOWPLAN_XML OFF
GO
-- enable parallel plan for DML with references to memory-optimized tables
DBCC TRACEON (9939)
GO
 
SET SHOWPLAN_XML ON
GO
-- Verify the query plan is parallel.
SELECT * INTO #temp FROM SalesOrder_MemOpt
GO
 
SET SHOWPLAN_XML OFF
GO
 
DBCC TRACEOFF (9939)
GO

參考資料

瞭解 Microsoft 用來說明軟體更新的 術語 。