对于索引存储,2008开始有两种优化方式,都是通过去除重复的数据减少存放的空间,使得原有的存放空间减少。更少的空间意味着更少的页,更少的页意味着查询过程中更少的I/O请求。分别为行压缩和页压缩
1.行压缩
第一种:降低行的体积。行压缩通过改变行的存储形式来达到目的,可以用在堆或者B_Tree上,启用行压缩,对应的一下功能会被启用。
行的原数据该表
定长数据会以变长格式存放
数值型数据类型也会存放成变长格式
--创建两个测试表作为对比
IF OBJECT_ID(‘dbo.NoCompression‘) IS NOT NULL
    DROP TABLE dbo.NoCompression
IF OBJECT_ID(‘dbo.RowCompression‘) IS NOT NULL
    DROP TABLE dbo.RowCompression
SELECT  SalesOrderID ,
        SalesOrderDetailID ,
        CarrierTrackingNumber ,
        OrderQty ,
        ProductID ,
        SpecialOfferID ,
        UnitPrice ,
        UnitPriceDiscount ,
        LineTotal ,
        rowguid ,
        Modi?edDate
INTO    dbo.NoCompression
FROM    Sales.SalesOrderDetail
SELECT  SalesOrderID ,
        SalesOrderDetailID ,
        CarrierTrackingNumber ,
        OrderQty ,
        ProductID ,
        SpecialOfferID ,
        UnitPrice ,
        UnitPriceDiscount ,
        LineTotal ,
        rowguid ,
        Modi?edDate
INTO    dbo.RowCompression
FROM    Sales.SalesOrderDetail
压缩功能是在CREATE 或ALTER INDEX语句的DATA_COMPRESSION上实现,压缩可以用于聚集和非聚集索引上。
下面的语句是行压缩,大概压缩了33%的空间
--没有压缩
CREATE CLUSTERED INDEX CLIX_NoCompression ON dbo.NoCompression
(SalesOrderID, SalesOrderDetailID);
--行压缩
CREATE CLUSTERED INDEX CLIX_RowCompression ON dbo.RowCompression
(SalesOrderID, SalesOrderDetailID)
WITH (DATA_COMPRESSION = ROW);
--检查使用的页
SELECT  OBJECT_NAME(object_id) AS table_name ,
        in_row_reserved_page_count
FROM    sys.dm_db_partition_stats
WHERE   object_id IN ( OBJECT_ID(‘dbo.NoCompression‘),
                       OBJECT_ID(‘dbo.RowCompression‘) )
有无行压缩的页数:

压缩并不仅仅带来存储空间的减少,还能通过减少数据页的方式提高查询性能。
   	   SET STATISTICS IO ON 
					   SELECT SalesOrderID,SalesOrderDetailID ,
                     CarrierTrackingNumber  FROM dbo.NoCompression
					   WHERE salesorderID BETWEEN 51500 AND 5200
					   SELECT SalesOrderID,SalesOrderDetailID ,
                     CarrierTrackingNumber  FROM dbo.RowCompression
					   WHERE salesorderID BETWEEN 51500 AND 5200
					   SET STATISTICS IO OFF
                       
对进行压缩时,需要考虑以下情况
1.压缩的前提是应该是对大表进行操作,
2.如果最大的函数超过了8060bytes,则压缩不能进行
3.非聚集索引不会继承堆或者聚集索引上的压缩位置。每个都需要手动进行
4.压缩时高频CPU开销的操作,不能频繁的进行
二。页压缩
页压缩也可以在堆和B-Tree结构中进行。页压缩通常比行压缩更有效,因为他包含了行压缩,前缀压缩和字典压缩。
在进行页压缩前,会先进行行压缩,然后在对页中前缀相同的数据进行压缩。
--创建测试表:
IF OBJECT_ID(‘dbo.PageCompression‘) IS NOT NULL
    DROP TABLE dbo.PageCompression
SELECT SalesOrderID
    ,SalesOrderDetailID
    ,CarrierTrackingNumber
    ,OrderQty
    ,ProductID
    ,SpecialOfferID
    ,UnitPrice
    ,UnitPriceDiscount
    ,LineTotal
    ,rowguid
    ,Modi?edDate
INTO dbo.PageCompression
FROM Sales.SalesOrderDetail
进行压缩处理:
CREATE CLUSTERED INDEX CLIX_PageCompression ON dbo.PageCompression
(SalesOrderID, SalesOrderDetailID)
WITH (DATA_COMPRESSION = PAGE);
SELECT  OBJECT_NAME(object_id) AS table_name ,
        in_row_reserved_page_count
FROM    sys.dm_db_partition_stats
WHERE   object_id IN ( OBJECT_ID(‘dbo.NoCompression‘),
                       OBJECT_ID(‘dbo.PageCompression‘) )
 
执行查询:
   SET STATISTICS IO ON 
					   SELECT SalesOrderID,SalesOrderDetailID
    ,CarrierTrackingNumber FROM dbo.PageCompression
					   WHERE SalesOrderID BETWEEN 51500 AND 5200
SET STATISTICS IO OFF
索引视图:
由于权限原因,查询可能不会返回很多数据,这时候视图可能作为一种候选方案,对于仅查询的静态数据,创建索引视图也是一个很好的方案。
不用索引视图的情况
	 SET STATISTICS IO ON
             SELECT  
			 psc.Name,
			 SUM(sod.LineTotal) AS SumLIneTotal,
			 SUM(sod.OrderQty) AS SumOrderQty,
			 AVG(sod.UnitPrice) AS AvgUnitPrice
			  FROM Sales.SalesOrderDetail sod
			 INNER JOIN Production.Product p ON sod.ProductID=p.ProductID
			 INNER JOIN Production.ProductSubcategory psc ON p.ProductSubcategoryID=psc.ProductSubcategoryID
			 GROUP BY psc.Name
			 ORDER BY psc.Name
 

创建索引视图:
 CREATE VIEW dbo.ProductSubcategorySummry
			 --用于创建索引视图
			 WITH  SCHEMABINDING
			 AS
             SELECT 
			 psc.Name,
			 SUM(sod.LineTotal) AS SumLIneTotal,
			 SUM(sod.OrderQty) AS SumOrderQty,
			 AVG(sod.UnitPrice) AS AvgUnitPrice
			 FROM Sales.SalesOrderDetail sod
			 INNER JOIN Production.Product p ON sod.ProductID =p.ProductID
			 INNER JOIN production.ProductSubcategory psc ON p.ProductSubcategoryID=psc.ProductSubcategoryID GROUP BY psc.Name;
--创建聚集索引 CREATE UNIQUE CLUSTERED INDEX CLIX_ProductSubcategorySummay ON dbo.ProductSubcategorySummry(Name) SET STATISTICS IO ON SELECT name,SumLineTotal,SumOrderQty,TotalUnitPrice/Occurances AS AvgUnitPrice FROM dbo.ProductSubcategorySummry ORDER BY name
在使用索引视图后,逻辑读下降了很多
索引视图在需要将多个表关联到一个单元中时非常有效,可以降低关联时的IO请求
索引视图的限制条件:
1.视图中所有列必须是确定的
2.索引视图必须使用SCHEMA_BINDING选项
3.聚集索引必须使用unique选项
4.引用的表必须具有带有架构名
5.某些汇总函数如AVG(),不能用于索引视图
原文:https://www.cnblogs.com/sunliyuan/p/8903435.html