SQL Server 列存储索引性能总结(3)——列存储的锁
程序员文章站
2022-07-15 10:37:40
...
接上文: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中的修改操作影响。