使用列儲存索引優化表?
我是表性能調整的新手。我有一個包含數百萬條記錄的平面表,沒有刪除更新操作。僅插入和讀取操作。
它的結構是這樣的:
目前索引:
PRIMARY CLUSTERED ON (Column1, Column2)
–> 因為基於這兩列的唯一性很重要。查詢將是以下任何一個:
-- query 1 select <all columns> from dbo.this_table where column1 = 'col1val1' -- query 2 select < all columns > from dbo.this_table where Column4= 'col4val1' and Column5='col5val2' and Column7='col7cval3' -- query 3 select < all columns > from dbo.this_table where Column4= 'col4val1' and Column6='col6val2' and Column7='col7cval3' -- query 4 select < all columns > from dbo.this_table where Column4= 'col4val1'
**如何針對 column4、column5、column6、column7 優化我的表?(最後 3 個查詢)**在我的情況下,儲存不是問題,但讀取數據的速度必須最低,所以我正在考慮列儲存。
有人可以建議什麼可以是索引以及以什麼組合?
我總共有 23 列,其中第 4 到 6 列實際上是 7 列。所有這 7 列都是具有重複值的 varchar。預計每個查詢可能會產生 0.01% 到 5% 的表。
column4
、column5
、column6
和的數據類型是什麼?column7
一般來說,這些列的值有多獨特?如果每列中存在高水平的潛在壓縮,列**儲存索引可能對您的案例有用,因為每列的值沒有很大的可變性。**較大的數據集(例如您的表格)通常會出現這種情況,但這確實取決於您,最好的選擇是進行測試。此外,您的表格有多寬(它有多少列)?因為如果使用傳統的行儲存索引和
INCLUDE
您要選擇的其他列而不是列儲存索引,這將是一個因素。最後,對於您的每個範例查詢,您估計將返回的表總行數的百分比是多少?
這些都是要考慮並影響不同索引執行情況的因素。關於列儲存索引,您可能還會發現ColumnScore.com有助於確定您的表是否符合列儲存索引的條件。您沒有
DELETE
或UPDATE
數據的事實是一個好的開始(儘管也不是硬性要求)。由於每個表只能使用一個列儲存索引,因此我認為值得嘗試針對最慢的案例進行優化。除非您可以嘗試
CREATE NONCLUSTERED COLUMNSTORE INDEX ix_TableName_ColumnNames ON TableName (Column4, Column5, Column6, Column7);
作為通用列儲存索引,但如果不進行測試,很難說這將如何滿足您的每個案例。此外,如果您想嘗試一些額外的行儲存索引,那麼這些將是我的建議作為起點(並且取決於您的表有多少列,可能
INCLUDE
還會在這些表的其他列中添加一個) :CREATE NONCLUSTERED INDEX ix_TableName_ColumnNames_2 ON TableName (Column4, Column5, Column7); CREATE NONCLUSTERED INDEX ix_TableName_ColumnNames_3 ON TableName (Column4, Column6, Column7);
列儲存索引中沒有查找之類的東西。只有掃描。您為索引定義的“鍵”中的列順序完全不相關。
但是, SQL Server可以做的是消除行組。建構列儲存索引時,SQL Server 讀取數據並一次建構 100 萬行的索引 - 這稱為行組。SQL Server 具有每個此類行組中每一列的最低和最高值的元數據。
想像一個查詢有
WHERE col = 23
SQL Server 將查看元數據以確定每個行組中該列的最低和最高值。如果 WHERE 子句中的列值不能存在於行組中,則不必讀取行組。這是行組消除。
您可以嘗試確保數據在這種情況下“對齊”,以便為來列獲得一個很好的行組分組(一個行組中的最低值,另一個行組中的下一個最低值等)。這不是通過鍵中列的順序來完成的,您必須創造性地在創建索引時以何種方式讀取數據。
因此,根據上述情況,您可能會為查詢 2、3 和 4 獲得一些不錯的行組消除,所有這些在 where 子句中都有 column4。假設您在建構索引時對該列進行了很好的對齊。至於查詢 1,除非 col1 和 col4 之間存在順序相關性,否則您可能會對該查詢的列儲存索引進行全面掃描。
接下來要考慮的是列儲存索引是否涵蓋您的查詢(具有查詢引用的所有列)。如果是,則在上述操作之後完成(掃描行組以查找行)。如果沒有,那麼您將進行查找以獲取每一行。如果選擇性低,那麼將會有很多查找,並且對優化器使用其他一些策略可能更有效。
以上是對事物如何工作的簡要說明。其餘的取決於您,因為我們不會使用您的數據和查詢。
此外,進一步的插入最終可能會“降低”索引的質量(在本例中為 column4 的對齊),您將考慮安排重建該列儲存索引是否可行。