SQL Server 列存储索引性能总结(9)——重建和重组聚集列存储索引所需的内存

接上文SQL Server 列存储索引性能总结(8)——列存储中的Dictionary,本文演示一下创建或重建及重组列存储索引时所需要的内存,因为在
SQL Server 列存储索引性能总结(5)——列存储等待信息中我们也看到了如果内存不足,会出现不少等待。

背景

   在数据导入列存储索引后,通常还会有不少行组没有被压缩,甚至全部没有被压缩,这个时候除了Tuple Mover之外,还可以通过手动触发,比如重组和重建索引,但是列存储通常时针对大表设计的,所以创建和重建过程需要很多的CPU/内存甚至I/O资源。如果这些资源不够,不仅处理过程很慢,还会影响数据库的其他正常操作。
   本文基于SQL Server On Linux(2019),使用ContosoRetailDW并且设置兼容级别为130(SQL 2016)作为演示,因为2016是一个临界点,非常多的功能在这个版本中变化。当然后续也可以改成2017/2019来测试。
   本文主要以FactOnlineSales这个表作为模板来做演示,因为数据量也比较多。
   接下来创建一个CCI的新表,然后用传统insert方式导入200万数据,这样就会有2个Delta Store,一个是Open,一个是Close。然后通过ALTER INDEX REORGANIZE和REBUILD来触发压缩机制,同时监控资源情况。这个虚拟机有4个core和20G内存。
在这里插入图片描述
   下面是建表和导数脚本,脚本会用20次,每次10万行来导入。

USE [ContosoRetailDW]
GO

DROP TABLE IF EXISTS dbo.FactOnlineSales_Test;

CREATE TABLE [dbo].[FactOnlineSales_Test](
	[OnlineSalesKey] [int] NOT NULL,
	[DateKey] [datetime] NOT NULL,
	[StoreKey] [int] NOT NULL,
	[ProductKey] [int] NOT NULL,
	[PromotionKey] [int] NOT NULL,
	[CurrencyKey] [int] NOT NULL,
	[CustomerKey] [int] NOT NULL,
	[SalesOrderNumber] [nvarchar](20) NOT NULL,
	[SalesOrderLineNumber] [int] NULL,
	[SalesQuantity] [int] NOT NULL,
	[SalesAmount] [money] NOT NULL,
	[ReturnQuantity] [int] NOT NULL,
	[ReturnAmount] [money] NULL,
	[DiscountQuantity] [int] NULL,
	[DiscountAmount] [money] NULL,
	[TotalCost] [money] NOT NULL,
	[UnitCost] [money] NULL,
	[UnitPrice] [money] NULL,
	[ETLLoadID] [int] NULL,
	[LoadDate] [datetime] NULL,
	[UpdateDate] [datetime] NULL,
	INDEX CCI CLUSTERED COLUMNSTORE
);

SET NOCOUNT ON
DECLARE @i as INT = 0;
DECLARE @offset as INT = 0;

WHILE @i < 20
BEGIN
	set @offset = @i * 100000;

	INSERT INTO dbo.FactOnlineSales_Test WITH (TABLOCK)
		(OnlineSalesKey, DateKey, StoreKey, ProductKey, PromotionKey, CurrencyKey, CustomerKey, SalesOrderNumber, SalesOrderLineNumber, SalesQuantity, SalesAmount, ReturnQuantity, ReturnAmount, DiscountQuantity, DiscountAmount, TotalCost, UnitCost, UnitPrice, ETLLoadID, LoadDate, UpdateDate)
	SELECT TOP 100000 OnlineSalesKey, DateKey, StoreKey, ProductKey, PromotionKey, CurrencyKey, CustomerKey, SalesOrderNumber, SalesOrderLineNumber, SalesQuantity, SalesAmount, ReturnQuantity, ReturnAmount, DiscountQuantity, DiscountAmount, TotalCost, UnitCost, UnitPrice, ETLLoadID, LoadDate, UpdateDate
		FROM dbo.FactOnlineSales	

	SET @i = @i + 1;
END

   首先我们先重组一下聚集列存储索引,同时在新窗口使用下面的DMV脚本查看内存使用情况。注意要在运行时执行,当重组完成之后是没有数据的:

--重组索引
alter index [CCI] 	on dbo.FactOnlineSales_Test reorganize WITH (COMPRESS_ALL_ROW_GROUPS = ON);
--新窗口打开并查看内存信息
SELECT cast(requested_memory_kb / 1024. as Decimal(9,2)) as RequestedMemoryMB
	,cast(granted_memory_kb / 1024. as Decimal(9,2)) as GrantedMemoryMB
	,cast(required_memory_kb / 1024. as Decimal(9,2)) as RequiredMemoryMB
	,cast(used_memory_kb / 1024. as Decimal(9,2)) as UsedMemoryMB
	,cast(max_used_memory_kb / 1024. as Decimal(9,2)) as MaxUsedMemoryMB
	FROM sys.dm_exec_query_memory_grants;

   结果如下:
在这里插入图片描述
   在20G的环境下,大概需要内存为 1342MB(RequiredMemoryMB),那接下来看看重建:

alter index [CCI] 	on dbo.FactOnlineSales_Test Rebuild 

在这里插入图片描述
   由于在运行过程实际使用的内存并不是一成不变,所以后面两个列的意义并不是非常大,我们几种看前面的三列。在重建过程,需要511MB内存。如果你留心的话,其实重建速度会快一点,不过不是快很多。而且如果你反复执行重建和重组,差距就不明显了,因为这时候索引已经很好地被维护了。
   但是这个现象可能说明一个事情——重建的开销更小,对于小资源的机器而言,使用重建是否会更好?单纯从数值上来对比,重建(REBUILD)还是更好的选择.。

提醒: Linux上的SQL Server,内存首先需要由Linux上配置,也就是分多少内存给SQL Server,然后SQL Server才能使用。长期使用Windows上SQL Server的读者来说需要注意。

   接下来我们降一下服务器内存试一下,调到5G,由于我使用的是Linux上的SQL Server所以需要先在Linux上调整,对于在Windows上的读者来说可以直接修改max server memory(MB)的值:

sudo /opt/mssql/bin/mssql-conf set memory.memorylimitmb 5120
EXEC sys.sp_configure N'show advanced options', N'1'  RECONFIGURE WITH OVERRIDE
GO
EXEC sys.sp_configure N'max server memory (MB)', N'5120'
GO
RECONFIGURE WITH OVERRIDE
GO
EXEC sys.sp_configure N'show advanced options', N'0'  RECONFIGURE WITH OVERRIDE
GO

   然后我们用同样的方式来测试,重组结果如下:
在这里插入图片描述
   重建结果如下:

在这里插入图片描述
   下面是整理数据:
在这里插入图片描述

小结

  从结果可以看出,重建的所需内存是几乎恒定的。而重组的内存是由变动,正如篇头那篇等待状态文章里面提到的,重组会尽可能使用所有资源,所以资源的可用性很大程度决定了重组的效率。
   那是否意味着重组就没有存在意义呢?当然不是,不管是列存储还是行存储,重组可以减少索引维护过程对正常操作的影响。虽然时间可能长一点。所以如果当你的系统在日常使用中需要整理碎片时,不妨考虑一下重组。

发布了192 篇原创文章 · 获赞 1268 · 访问量 250万+

猜你喜欢

转载自blog.csdn.net/DBA_Huangzj/article/details/104998017