接上文:SQL Server 列存儲索引性能總結(2)——獲取元數據信息,本文介紹列存儲相關的鎖
現在在TempDB中重新建表:
IF OBJECT_ID('dbo.CCTest', 'U') IS NOT NULL
drop table dbo.CCTest;
create table dbo.CCTest(
id int not null,
name varchar(50) not null,
lastname varchar(50) not null );
GO
create clustered columnstore index CCL_CCTest
on dbo.CCTest;
GO
然後用下面這個語句檢查鎖情況:
SELECT dm_tran_locks.request_session_id,
dm_tran_locks.resource_database_id,
DB_NAME(dm_tran_locks.resource_database_id) AS dbname,
CASE
WHEN resource_type = 'object'
THEN OBJECT_NAME(dm_tran_locks.resource_associated_entity_id)
ELSE OBJECT_NAME(partitions.OBJECT_ID)
END AS ObjectName,
partitions.index_id,
indexes.name AS index_name,
dm_tran_locks.resource_type,
dm_tran_locks.resource_description,
dm_tran_locks.resource_associated_entity_id,
dm_tran_locks.request_mode,
dm_tran_locks.request_status
FROM sys.dm_tran_locks
LEFT JOIN sys.partitions ON partitions.hobt_id = dm_tran_locks.resource_associated_entity_id
JOIN sys.indexes ON indexes.OBJECT_ID = partitions.OBJECT_ID AND indexes.index_id = partitions.index_id
WHERE resource_associated_entity_id > 0
AND resource_database_id = DB_ID()
ORDER BY request_session_id, resource_associated_entity_id
接下來開始模擬事務,開始事務插入數據,但是不回滾或者提交:
begin tran
insert into dbo.CCTest ( id, name, lastname ) values ( 1, 'SomeName_', 'SomeLastName_' );
執行上面的查詢鎖的命令可以看到下面的樣子:
有一個IX(意向排他鎖)在整個行組上,這裏也就是Delta Store。現在先rollback前面的insert。除非使用Bulk insert,否則剛纔的begin tran會阻塞其他insert語句對這個表的操作。所以如果可以,對聚集列存儲索引(後稱CCI,Clustered columnstore index)的導入更加偏向使用Bulk insert。
接下來把Delta Store填滿,也就是1048576行:
declare @i as int;
declare @max as int;
select @max = isnull(max(id),0) from dbo.CCTest;
set @i = 1;
begin tran
while @i <= 1048576
begin
insert into dbo.CCTest ( id, name, lastname ) values ( @max + @i, 'SomeName_', 'SomeLastName_' );
set @i = @i + 1;
end;
commit;
然後再開啓事務插入一行以後,再看看行組的情況,現在有兩行,一個是Closed,一個是open的用於接收新數據:
先看看鎖的情況,這個時候rowgroup全部被鎖住,也就是說Tuple Mover沒辦法運行。
記得提交事務。
小結
就目前的測試結果而言,CCI還是不適合應對高負載的OLTP,因爲它很容易就被OLTP中的修改操作影響。