索引存儲


對於索引存儲,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 ,
        ModifiedDate
INTO    dbo.NoCompression
FROM    Sales.SalesOrderDetail
SELECT  SalesOrderID ,
        SalesOrderDetailID ,
        CarrierTrackingNumber ,
        OrderQty ,
        ProductID ,
        SpecialOfferID ,
        UnitPrice ,
        UnitPriceDiscount ,
        LineTotal ,
        rowguid ,
        ModifiedDate
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
    ,ModifiedDate
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(),不能用於索引視圖

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM