SQL Server ->> SQL Server 2016重要功能改進之 -- INSERT SELECT時並發插入數據


SQL Server 2016對INSERT INTO XXXX SELECT語句進行了優化,在某些情況下可以觸發數據的並行插入,但是要求兼容模式是130(SQL Server 2016)以及在插入的時候加表鎖(WITH(TABLOCK))。那是不是大部分情況都能觸發,並不是。除了上面提到的兩點必要條件,還有苛刻的限制條件:1)不能有額外的索引,目標表只能是堆或者聚集索引的存儲模式;2)表不能有SEQUENCE字段或者IDENTITY字段;當然這兩點是基於目標表是B樹或者堆存儲結構的表。SQL Server 2016對ColumnStored Index做了大量優化,加入Batch Mode,也就是數據在插入到列存儲索引的時候就是並行插入的。

首先第一種情況是從一張表select insert into到另外一張表。這種情況是可以觸發並行插入的。但是和具體有多少行有關系。整個測試中我測試了5W、10W、100W行。結果發現還要和執行計划扯上關系。如果第一次插入是10W行或者100W行都觸發了並行,但是第二次改成5W行則沒有並行,當插入5W行后執行計划被緩存了,再插入100W行也不會觸發並行。只有重編譯或者重建表索引導致查詢語句下次重編譯才會觸發並行(插入100W行)。而觸發並行的臨界點,在測試例子中是10W行。第二種情況是多張表連接后插入數據。這個例子里面還要分開來看。就是目標表是啟用了兼容模式是130,而且也加了表鎖,但是源表的數據庫可能不是SQL Server 2016的兼容模式,是否對結果造成影響。按道理應該是不會,因為並行是對數據插入的並行,而不影響連接表的庫的來源或者兼容模式是什么。但是測試下來發現,即便我插入了100W行也沒能觸發並行。

 

情況1腳本

CREATE TABLE [dbo].[Table_1](
    [col1] [int] NULL,
    [col2] [nvarchar](50) NULL,
    [col3] [datetime] NULL
) ON [PRIMARY]

GO

CREATE TABLE [dbo].[Table_2](
    [col1] [int] NULL,
    [col2] [nvarchar](50) NULL,
    [col3] [datetime] NULL
) ON [PRIMARY]

GO


insert [dbo].[Table_1]WITH(TABLOCK)
select TOP 1000000 CHECKSUM(NEWID()), REPLICATE('a',50), getdate()
from sys.columns a, sys.columns b

insert [dbo].[Table_2]WITH(TABLOCK)
select * from [dbo].[Table_1]
OPTION (RECOMPILE)

TRUNCATE TABLE [dbo].[Table_1]
TRUNCATE TABLE [dbo].[Table_2]

 

參考:

SQLSweet16!, Episode 3: Parallel INSERT … SELECT

Real World Parallel INSERT…SELECT: What else you need to know!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM