資料行存放區索引

「xVelocity 記憶體最佳化的資料行存放區索引」(xVelocity Memory Optimized Columnstore Index) 會分組並儲存每個資料行的資料,然後再聯結所有的資料行,以完成整個索引。 不同於傳統的索引,傳統的索引會分組並儲存每一個資料列的資料,然後聯結所有資料列,以完成整個索引。 對於某些類型的查詢,SQL Server 查詢處理器可以運用資料行存放區配置,大幅減少查詢時間。 隨著資料倉儲的快速成長,決策支援與 BI 應用程式必須迎頭趕上,才可縮短讀取龐大資料集的時間,並且正確地將這些資料處理成可用的資訊與知識。 大幅成長的資料量與不斷增加的需求,對於效能維護與提升是一大挑戰。 SQL Server 資料行存放區索引技術十分適合典型的資料集資料倉儲。 資料行存放區索引可以加快常用資料倉儲查詢 (如篩選、彙總、群組及星型聯結查詢等) 的速度,大幅改善使用者的資料倉儲經驗。

目錄

基本概念

  • 基本概念:資料行存放區索引說明

  • 基本概念:資料行存放區索引的限制事項

  • 示範範例:分割資料表上的資料行存放區索引

  • 基本概念:典型資料行存放區索引案例

  • 基本概念:點陣圖篩選最佳化

最佳作法

  • 最佳作法:更新資料行存放區索引中的資料

  • 最佳作法:選擇資料行存放區索引的資料行

  • 最佳作法:分割資料表

如何

  • 如何:建立資料行存放區索引

  • 如何:決定資料行存放區索引的大小

  • 如何:疑難排解資料行存放區索引效能

基本概念:資料行存放區索引說明

SQL Server Database Engine 的資料行存放區索引可大幅縮短常用資料倉儲查詢的處理時間。 資料倉儲工作負載通常意謂著大量資料的彙總。 一般用於資料倉儲及決策支援系統以改進效能的技術為預先計算的摘要資料表、索引檢視表、OLAP Cube 等。 這些技術雖可顯著地加快查詢處理速度,卻往往缺乏彈性、不易維護,且必須個別針對各個查詢問題進行設計。

例如,假設事實資料表 F1 具有維度索引鍵資料行 dk1 及 dk2。 M 代表彙總函式,例如 SUM。 除了可以在每次參考 M(dk1) 的查詢執行時,就資料行 dk1 計算 M 之外,也可建立並使用摘要資料表 F2(dk1, M) 預先計算結果,加快查詢執行的速度。 但如有新查詢需要參考 M(dk2),也必須建立內含此資訊的新摘要資料表 F3(dk2, M)。 當資料表的資料行數增加,同時又有許多函數時,此方法就變得難以維護,且不易涵蓋所有需要的查詢。

這些額外的工作量將造成使用者極大的負荷。 使用 SQL Server 資料行存放區索引,可以減輕使用者因為其他方案所造成的麻煩。 資料行存放區索引也可讓查詢在極短的時間內即求出計算結果,完全無需預先計算。

SQL Server 資料行存放區技術的關鍵特性包括:

  • 單欄式資料格式:不同於傳統使用資料列組織資料 (稱為「資料列存放區」(Rowstore)) 的方式,在具有資料行存放區索引的單欄式資料庫系統中 (如 SQL Server),資料會一次分組成一個資料行加以儲存。 SQL Server 查詢處理可利用此新資料配置大幅縮短查詢的時間。

  • 更快地查詢結果:下列因素讓資料行存放區索引可以更快速地產生結果:

    • 因為只需要讀取所需的資料行, 所以從磁碟讀取到記憶體,再從記憶體移至處理器快取的資料量也相對變少了。

    • 資料行會高度地壓縮, 因此減少了必須讀取及移動的位元組數。

    • 大多數的查詢不太需要觸及資料表的所有資料行, 也因此有許多資料行從不會被讀取到記憶體。 此特性加上先進的壓縮法,可以有效改善緩衝集區的使用率,從而降低整體的 I/O。

    • 進階查詢執行技術,可以有效率地處理資料行區塊 (稱為「批次」(Batch)),從而降低 CPU 使用率。

  • 索引鍵資料行:資料行存放區索引不具索引鍵資料行的概念,因此資料行存放區索引沒有索引的索引鍵資料行數限制 (16) 問題。

  • 叢集索引鍵:基底資料表如果是叢集索引,則叢集索引鍵中的所有資料行皆必須存在於非叢集的資料行存放區索引中。 叢集索引鍵如有任何資料行未列在建立索引陳述式中,其會自動加入資料行存放區索引。

  • 資料分割:資料行存放區索引可與資料表資料分割並用。 您無須變更資料表資料分割語法。 分割資料表的資料行存放區索引的資料分割必須與基底資料表一致。 因此當分割資料行是資料行存放區索引的資料行時,只可對分割資料表建立非叢集的資料行存放區索引。

  • 記錄大小:資料行存放區索引也不具 900 個位元組的索引鍵記錄大小上限。

  • 查詢處理:除了資料行存放區索引之外,SQL Server 還引進了批次處理功能,可以充分發揮以單欄形式整理資料的優點。 資料行存放區架構與批次處理對於效能提升皆有極大的助益,但在效能問題的起因不只一項時,其調查過程可能更為複雜。

  • 資料表無法更新:SQL Server 2012 無法讓您更新具有資料行存放區索引的資料表。 如需相關因應措施,請參閱<最佳作法:更新資料行存放區索引中的資料>。

如需如何建立資料行存放區索引的語法,請參閱<CREATE COLUMNSTORE INDEX (Transact-SQL)>。

資料類型

一般商務資料類型可包含在資料行存放區索引中。 下列資料類型可包含在資料行存放區索引中。

  • char 及varchar

  • nchar 和 nvarchar (varchar(max) 和 nvarchar(max) 除外)

  • decimal (和 numeric) (有效位數大於 18 個位數的除外)

  • int、bigint、smallint 和 tinyint

  • float (和 real)

  • bit

  • money 和smallmoney

  • 所有日期和時間資料類型 (有效位數大於 2 的 datetimeoffset 除外)

下列資料類型不可加入資料行存放區索引:

  • binary 及varbinary

  • ntext、text 及 image

  • varchar(max) 及nvarchar(max)

  • uniqueidentifier

  • rowversion (及 timestamp)

  • sql_variant

  • 有效位數大於 18 個位數的 decimal (和 numeric)

  • 有效位數大於 2 的 datetimeoffset

  • CLR 類型 (hierarchyid 和空間類型)

  • xml

可能會造成效能不佳

對大型資料表使用資料行存放區索引,大多可以改善決策支援查詢的效能,但可能會造成某些查詢甚至整體工作負載的效能變差。 在成本的考量之下,查詢最佳化工具通常會決定只在能夠改善整體查詢效能的情況下,才使用資料行存放區索引。 最佳化工具所使用的成本模型並非絕對精準,因此在某些情況下,或許使用資料列存放區 (B 型樹狀目錄或堆積) 存取資料表可能效能更佳,但最佳化工具卻選擇使用資料行存放區索引。 發生這種情況時,可以使用 IGNORE_NONCLUSTERED_COLUMNSTORE_INDEX 查詢提示,或使用索引提示,指示最佳化工具選擇使用資料列存放區索引。 最佳化工具可能仍會包含一些資料行存放區索引的資訊。 因此在極少數的情況下,此選項可能無法解決效能問題。 當資料行存放區索引無法改善您的工作負載效能,而您也無法利用索引提示更正錯誤時,可以卸除資料行存放區索引,回復成資料列存放區處理。

問題區域

SQL Server 資料行存放區索引與採用資料行的查詢處理,會就一般具有大型事實資料表,並與星狀結構描述組態之中小型維度資料表相聯結,然後再加以分組及彙總的資料倉儲查詢進行最佳化。 事實資料表中的資料列數雖然十分龐大,但這些查詢通常會傳回相當精簡的結果集,因為資料已經過彙總。 當發生下列一種或多種情況時,使用資料行存放區索引的查詢效能可能會變慢。

  • 資料未經彙總,造成結果集變得十分龐大 (傳回大型結果集原本就較傳回小型結果集來得慢)。

  • 無聯結、篩選或彙總。 在此情況下無法使用批次處理。 因此,使用資料行存放區索引便只剩下資料壓縮及讀取較少資料行兩項優點。

  • 兩大資料聯結之後所建立的雜湊資料表,必須大到記憶體無法容納而溢入磁碟。

  • 傳回了多個資料行,並因此而導致擷取了多個資料行存放區索引。

  • 使用資料行存放區索引之資料表的聯結條件包含了多個資料行。

如果是因為上述原因導致資料行存放區處理變慢,可以使用前文所述方法解決問題。

回到頁首

基本概念:資料行存放區索引的限制事項

基本限制

資料行存放區索引:

  • 不能有 1024 個以上的資料行。

  • 不可叢集化。 只能使用非叢集資料行存放區索引。

  • 不能是唯一索引。

  • 無法在檢視表或索引檢視表上建立。

  • 不能包含疏鬆資料行。

  • 不可做為主索引鍵或外部索引鍵使用。

  • 無法使用 ALTER INDEX 陳述式加以變更。 請改為卸除並重新建立資料行存放區索引 (您可以使用 ALTER INDEX 停用並重建資料行存放區索引)。

  • 不可使用 INCLUDE 關鍵字來建立。

  • 不可包含 ASC 或 DESC 關鍵字排序索引。 資料行存放區索引是依據壓縮演算法來排序。 索引中不允許排序。 搜尋演算法可能會排序從資料行存放區索引中選取的值,但是您必須使用 ORDER BY 子句以確保結果集的排序。

  • 請勿以傳統索引的方式使用或保留統計資料。

  • 不能包含具有 FILESTREAM 屬性的資料行。 資料表中未在索引內使用的其他資料行可以包含 FILESTREAM 屬性。

無法更新具有資料行存放區索引的資料表

如需相關因應措施,請參閱<最佳作法:更新資料行存放區索引中的資料>。

記憶體不足的影響

資料行存放區處理適合在記憶體中進行。 當可用的記憶體不足時,SQL Server 會採取因應措施,將資料及大多數的資料結構溢入磁碟。 如有嚴格的記憶體限制,處理將會改用資料列存放區。 在某些情況下,也可能選擇了資料行存放區索引做為存取方法,但記憶體卻不足以建立所需的資料結構。 當資料行存放區作業因為程式碼執行速度過慢而無法完成時,如果查詢遇到記憶體嚴重不足的情況,效能可能會有些許折扣。 每個查詢所需要的記憶體大小會隨查詢的性質而不同。 建立資料行存放區索引所需的記憶體約為 8 MB 乘以索引中的資料行數,再乘以 DOP (平行處理的程度)。一般而言,記憶體需求與字串資料行數成正比。 因此減少 DOP 可以降低建立資料行存放區索引的記憶體需求。

某些運算式的計算速度會較其他運算式快。

使用資料行存放區索引時,一些常用運算式會使用批次模式進行計算,而不會採用一次計算一列的模式。 除了資料行存放區索引既有的優點之外,批次模式還可加快查詢的速度。 並非每個查詢執行運算子都可使用批次模式處理。

資料行存放區索引不支援 SEEK。

如果查詢只需要傳回資料列的一小部分,則最佳化工具不可能選取資料行存放區索引 (例如「大海撈針」(Needle-in-the-haystack) 式的查詢)。 如果使用 FORCESEEK 資料表提示,最佳化工具將不會考慮使用資料行存放區索引。

資料行存放區索引無法與下列功能並用:

  • 頁面和資料列壓縮,以及 vardecimal 儲存格式 (資料行存放區索引已使用不同格式壓縮)。

  • 複寫

  • 變更追蹤

  • 異動資料擷取

  • 檔案資料流

回到頁首

示範範例:分割資料表上的資料行存放區索引

本主題中的範例將使用先前在 AdventureWorksDW2012 範例資料庫中所建立的分割資料表 FactResellerSalesPtnd。 如果要測試分割資料表中的資料行存放區索引,請連接至 AdventureWorksDW2012 資料庫,然後執行下列程式碼,建立分割版的事實資料表。

[!附註]

如需有關範例資料庫的詳細資訊,以及如何下載資料庫的指示,請參閱 AdventureWorks 範例資料庫

建立 FactResellerSalesPtnd 資料表

  • 執行下列程式碼,建立分割版的 FactResellerSales 資料表,並將其命名為 FactResellerSalesPtnd。

    USE AdventureWorksDW2012;
    GO
    
    CREATE PARTITION FUNCTION [ByOrderDateMonthPF](int) AS RANGE RIGHT 
    FOR VALUES (
        20050701, 20050801, 20050901, 20051001, 20051101, 20051201, 
        20060101, 20060201, 20060301, 20060401, 20060501, 20060601, 
        20060701, 20060801, 20060901, 20061001, 20061101, 20061201, 
        20070101, 20070201, 20070301, 20070401, 20070501, 20070601, 
        20070701, 20070801, 20070901, 20071001, 20071101, 20071201, 
        20080101, 20080201, 20080301, 20080401, 20080501, 20080601, 
        20080701, 20080801, 20080901, 20081001, 20081101, 20081201
    ) 
    GO
    
    CREATE PARTITION SCHEME [ByOrderDateMonthRange] 
    AS PARTITION [ByOrderDateMonthPF] 
    ALL TO ([PRIMARY]) 
    GO
    
    -- Create a partitioned version of the FactResellerSales table
    CREATE TABLE [dbo].[FactResellerSalesPtnd]( 
        [ProductKey] [int] NOT NULL, 
        [OrderDateKey] [int] NOT NULL, 
        [DueDateKey] [int] NOT NULL, 
        [ShipDateKey] [int] NOT NULL, 
        [CustomerKey] [int] NOT NULL, 
        [EmployeeKey] [int] NOT NULL, 
        [PromotionKey] [int] NOT NULL, 
        [CurrencyKey] [int] NOT NULL, 
        [SalesTerritoryKey] [int] NOT NULL, 
        [SalesOrderNumber] [nvarchar](20) NOT NULL, 
        [SalesOrderLineNumber] [tinyint] NOT NULL, 
        [RevisionNumber] [tinyint] NULL, 
        [OrderQuantity] [smallint] NULL, 
        [UnitPrice] [money] NULL, 
        [ExtendedAmount] [money] NULL, 
        [UnitPriceDiscountPct] [float] NULL, 
        [DiscountAmount] [float] NULL, 
        [ProductStandardCost] [money] NULL, 
        [TotalProductCost] [money] NULL, 
        [SalesAmount] [money] NULL, 
        [TaxAmt] [money] NULL, 
        [Freight] [money] NULL, 
        [CarrierTrackingNumber] [nvarchar](25) NULL, 
        [CustomerPONumber] [nvarchar](25) NULL,
        OrderDate [datetime] NULL,
        DueDate [datetime] NULL,
        ShipDate [datetime] NULL
    ) ON ByOrderDateMonthRange(OrderDateKey);
    GO
    
    -- Using simple or bulk logged recovery mode, and then the TABLOCK 
    -- hint on the target table of the INSERT…SELECT is a best practice
    -- because it causes minimal logging and is therefore much faster.
    ALTER DATABASE AdventureWorksDW2012 SET RECOVERY SIMPLE;
    GO
    
    -- Copy the data from the FactResellerSales into the new table
    INSERT INTO dbo.FactResellerSalesPtnd WITH(TABLOCK)
    SELECT * FROM dbo.FactResellerSales;
    GO
    
    -- Create the columnstore index
    CREATE NONCLUSTERED COLUMNSTORE INDEX [csindx_FactResellerSalesPtnd]
    ON [FactResellerSalesPtnd]
    ( 
        [ProductKey], 
        [OrderDateKey], 
        [DueDateKey], 
        [ShipDateKey], 
        [CustomerKey], 
        [EmployeeKey], 
        [PromotionKey], 
        [CurrencyKey], 
        [SalesTerritoryKey], 
        [SalesOrderNumber], 
        [SalesOrderLineNumber], 
        [RevisionNumber], 
        [OrderQuantity], 
        [UnitPrice], 
        [ExtendedAmount], 
        [UnitPriceDiscountPct], 
        [DiscountAmount], 
        [ProductStandardCost], 
        [TotalProductCost], 
        [SalesAmount], 
        [TaxAmt], 
        [Freight], 
        [CarrierTrackingNumber], 
        [CustomerPONumber], 
        [OrderDate],
        [DueDate],
        [ShipDate]
    );
    

現在請執行採用資料行存放區索引的查詢,並確認已使用了資料行存放區索引。

測試資料行存放區索引

  1. 按 Ctrl+M,或在 [查詢] 功能表上,選取 [包括實際執行計畫]。 這會開啟 SQL Server Management Studio 實際使用之執行計畫的圖形表示。

  2. 在 [查詢編輯器] 視窗中執行下列查詢。

    SELECT SalesTerritoryKey, SUM(ExtendedAmount) AS SalesByTerritory
    FROM FactResellerSalesPtnd
    GROUP BY SalesTerritoryKey;
    

    [結果] 視窗的 [執行計畫] 索引標籤底下,確認查詢計畫已選取了非叢集 csindx_FactResellerSalesPtnd 索引的索引掃描。

    [!附註]

    如需有關圖形化 Showplan 圖示的詳細資訊,請參閱<執行程序邏輯和實體運算子參考>。

    回到頁首

基本概念:典型資料行存放區索引案例

星形或雪花形資料庫結構描述一般常見於維度資料倉儲及資料超市,其擷取資料的速度較資料操作的效率更為重要。 SQL Server 2012 的資料行存放區技術可以偵測並加速對星形及雪花形結構描述的查詢。

範例:

[!附註]

下列範例因為資料表不夠大,所以無法使用批次處理。 批次執行模式 (如平行處理) 應用於比較費時的查詢。

A:聯結兩個資料表的彙總查詢

  • 假想有一個星形查詢會計算我們每季所售出的 215 號產品。 事實資料表 FactResellerSalesPtnd 會在 OrderDateKey 資料行上進行分割。 其中維度資料表 DimDate 會透過日期索引鍵之主要索引鍵對外部索引鍵的關係,連結到事實資料表。

    SELECT d.CalendarYear,
        d.CalendarQuarter,
        COUNT(*) AS NumberSold
    FROM dbo.FactResellerSalesPtnd AS f
        JOIN dbo.DimDate AS d
        ON f.OrderDateKey = d.DateKey
    WHERE ProductKey = 215
    GROUP BY d.CalendarYear, d.CalendarQuarter
    ORDER BY d.CalendarYear, d.CalendarQuarter;
    

除此之外,也有一些查詢只會針對單一資料表。 在此情況下,SQL Server 也會嘗試使用批次執行與資料行存放技術加速查詢。

B:針對單一資料表的簡單彙總查詢

  • 事實資料表 FactResellerSalesPtnd 會在 OrderDateKey 資料行上進行分割。 下列查詢會傳回資料列數與訂單數。

    SELECT COUNT(*) AS NumberOfRows, 
        COUNT(DISTINCT(f.SalesOrderNumber)) AS NumberOfOrders
    FROM dbo.FactResellerSalesPtnd AS f;
    

    對於典型的資料倉儲案例的查詢,如果在執行查詢時使用了資料行存放區索引與批次執行模式時,其速度一般可加快 1.5 至 10 倍左右。 對於一些星型聯結查詢,其加速程度更是大上許多。

基本概念:點陣圖篩選最佳化

除了單欄式格式的資料配置之外,SQL Server 還會使用傳遞至儲存引擎的點陣圖篩選,強化查詢執行的效能。 點陣圖篩選會在實作聯結之前,先減少所包含的資料列數,藉此縮減聯結運算子所處理的資料列數,從而加快查詢執行的速度。 此點陣圖會在建立雜湊聯結時建立,但真正的點陣圖檢查,則會在探查雜湊聯結時執行。 您可使用圖形化或 XML 執行計畫觀察點陣圖篩選的使用狀況。

最佳作法:更新資料行存放區索引中的資料

您無法更新具有資料行存放區索引的資料表。 此問題有三種因應方式。

  • 如果要更新具有資料行存放區索引的資料表,請卸除資料行存放區索引,並執行所有要求的 INSERT、DELETE、UPDATE 或 MERGE 作業,然後重建資料行存放區索引。

  • 分割資料表並切換資料分割。 進行大量插入時,請將資料插入暫存資料表,並建立暫存資料表的資料行存放區索引,然後將暫存資料表切換至空的資料分割。 如要進行其他更新,請將分割從主要資料表切換至暫存資料表,並停用或卸除暫存資料表的資料行存放區索引,然後執行更新作業,接著再重新建立暫存資料表的資料行存放區索引,最後切換回主要資料表。

  • 將靜態資料置入具有資料行存放區索引的主要資料表,然後新資料及最近可能會有所變更的資料置入另一張具有相同結構描述,但不具資料行存放區索引的資料表中。 將更新套用到包含最新資料的資料表。 如果要查詢資料,請個別針對這兩個資料表,將查詢重寫成兩個查詢,然後使用 UNION ALL 結合兩個結果集。 大型主要資料表的子查詢將可獲益於資料行存放區索引。 如果要更新的資料表十分小,即使不具備資料行存放區索引,對於效能的影響也不明顯。 您雖然也可查詢兩個資料表之 UNION ALL 的檢視表,但對於效能提升的感受可能並不明顯。 效能依查詢計畫而異,而查詢計畫又取決於查詢、資料及基數估算。 使用檢視表的好處在於檢視表的 INSTEAD OF 觸發程序可以將更新轉移至不具資料行存放區索引的資料表,且使用者與應用程式皆不會受到此檢視機制的干擾。 如果要並用上述任一種方法與 UNION ALL,可利用一般查詢測試效能,從而確認使用這些方法的便利性,是否大於效能提升的優點。

[!附註]

請勿利用建立資料行存放區索引的方式,將資料表設成唯讀。 後續版本不一定會對更新具資料表存放區索引的資料表設限。 如需將資料表設成唯讀,請建立唯讀檔案群組,然後將資料表移至該檔案群組中。

最佳作法:選擇資料行存放區索引的資料行

有些資料行存放區索引所帶來的效能提升,來自於可以減少查詢處理所讀取及操作之資料頁數的資料壓縮技術。 壓縮技術對於具有大量重複值之字元或數值資料行的效果最為顯著。 例如,維度資料表可能包含郵遞區號、城市及銷售區域等資料行。 假使每個城市都具有許多的郵遞區號,又假使每個銷售區域各有許多城市,則銷售區域資料行的壓縮程度將會最高,城市資料行的壓縮程度會稍低,郵遞區號的壓縮程度最低。 雖然所有資料行皆可用為資料行存放區索引,但將銷售區域資料行加入資料行存放區索引的效益將會最大,而加入郵遞區號的效益將會最少。

回到頁首

最佳作法:分割資料表

資料行存放區索引專為支援進行大型資料倉儲的查詢而設計,而資料分割又是大型資料倉儲中常見的狀況。 具有資料行儲存區索引之資料表內的資料如果必須定時更新,建議分割資料。 如需有關如何更新資料行存放區索引資料分割的詳細資訊,請參閱上一節的最佳作法:更新資料行存放區索引中的資料。

回到頁首

如何:建立資料行存放區索引

建立資料行存放區索引與建立其他索引相同。 您可以使用 Transact-SQL 或使用 SQL Server Management Studio 圖形化工具建立資料行存放區索引。

使用 Transact-SQL 建立資料行存放區索引

  • 在 [查詢編輯器] 視窗中執行 CREATE COLUMNSTORE INDEX 陳述式。 如需範例,請參閱上述的<建立 FactResellerSalesPtnd 資料表>。 如需詳細資訊,請參閱<CREATE COLUMNSTORE INDEX (Transact-SQL)>。

使用 SQL Server Management Studio 建立資料行存放區索引

  1. 在 Management Studio 中,使用 [物件總管] 連接到 SQL Server Database Engine 的執行個體。

  2. 在 [物件總管] 中,依序展開 SQL Server 執行個體、[資料庫]、資料庫及資料表,再以滑鼠右鍵按一下該資料表,然後指向 [新增索引],再按一下 [非叢集資料行存放區索引]

  3. [索引名稱] 對話方塊中的 [一般] 索引標籤底下,輸入新索引的名稱,然後按一下 [加入]

  4. [選取資料行] 對話方塊中,選取要加入資料行存放區索引的資料行,然後按兩下 [確定],以建立索引。

如何:決定資料行存放區索引的大小

資料行存放區索引由區段及字典組成。 下列範例示範如何藉由結合 sys.column_store_segments 及 sys.column_store_dictionaries 的 on_disk_size 資料行,確定資料行存放區索引的整體大小 (在 FactResellerSalesPtnd 資料表上)。

SELECT SUM(on_disk_size_MB) AS TotalSizeInMB
FROM
(
   (SELECT SUM(css.on_disk_size)/(1024.0*1024.0) on_disk_size_MB
    FROM sys.indexes AS i
    JOIN sys.partitions AS p
        ON i.object_id = p.object_id 
    JOIN sys.column_store_segments AS css
        ON css.hobt_id = p.hobt_id
    WHERE i.object_id = object_id('FactResellerSalesPtnd') 
    AND i.type_desc = 'NONCLUSTERED COLUMNSTORE') 
  UNION ALL
   (SELECT SUM(csd.on_disk_size)/(1024.0*1024.0) on_disk_size_MB
    FROM sys.indexes AS i
    JOIN sys.partitions AS p
        ON i.object_id = p.object_id 
    JOIN sys.column_store_dictionaries AS csd
        ON csd.hobt_id = p.hobt_id
    WHERE i.object_id = object_id('FactResellerSalesPtnd') 
    AND i.type_desc = 'NONCLUSTERED COLUMNSTORE') 
) AS SegmentsPlusDictionary

如何:疑難排解資料行存放區索引效能

如需確認有無使用資料行存放區索引,可檢視查詢執行計畫。 若已達到最大效能,三個元素會同時出現。

  • 查詢執行計畫位於資料行存放區索引中。

    資料行存放區索引掃描

    資料行存放區索引掃描運算子圖示

    如未使用資料行存放區索引,而您認為資料行存放有助於提升查詢效能,可以使用 WITH (INDEX(<indexname>)) 提示強制使用資料行存放區索引並評估查詢效能。 下列範例示範如何使用索引提示進行查詢。

    SELECT d.CalendarYear,
        d.CalendarQuarter,
        COUNT(*) AS NumberSold
    FROM dbo.FactResellerSalesPtnd AS f WITH (INDEX(csindx_FactResellerSalesPtnd))
        JOIN dbo.DimDate AS d
        ON f.OrderDateKey = d.DateKey
    WHERE ProductKey = 215
    GROUP BY d.CalendarYear, d.CalendarQuarter
    ORDER BY d.CalendarYear, d.CalendarQuarter;
    
  • 當您將指標移至圖形化查詢計畫中的資料行存放區索引圖示上方時,會將實際的執行模式列為批次,而不會列為資料列。

  • 圖形化執行計畫中如有出現點陣圖實體運算子圖示,表示點陣圖篩選會在聯結作業開始之前減少資料列數。

    點陣圖運算子圖示

    點陣圖運算子圖示

回到頁首

相關工作

CREATE COLUMNSTORE INDEX (Transact-SQL)

相關內容

sys.column_store_dictionaries (Transact-SQL)

sys.column_store_segments (Transact-SQL)