欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

   执行上面的查询锁的命令可以看到下面的样子:
SQL Server 列存储索引性能总结(3)——列存储的锁
   有一个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;

SQL Server 列存储索引性能总结(3)——列存储的锁
   然后再开启事务插入一行以后,再看看行组的情况,现在有两行,一个是Closed,一个是open的用于接收新数据:
SQL Server 列存储索引性能总结(3)——列存储的锁
   先看看锁的情况,这个时候rowgroup全部被锁住,也就是说Tuple Mover没办法运行。
SQL Server 列存储索引性能总结(3)——列存储的锁
   记得提交事务。

小结

   就目前的测试结果而言,CCI还是不适合应对高负载的OLTP,因为它很容易就被OLTP中的修改操作影响。