[SQL SERVER][Memo]Index組合比較測試
我想大家都會建立Index,但建立Index的組合卻有很多種
而通常針對一句效能差的Sql Statement,也都是加Index居多
但有時所建的Index並不是最佳組合,這裡我大概測試一下各種組合
順便記錄一下。
Table初始相關資訊
假設有一句SQL Statement需要調校,搜尋資料筆數有1299071,我們準備來測試各種組合狀況
select t1.POLICY_NO,t1.TRAN_DATE from dbo.QTPLG t1
where t1.TRAN_DATE between '2007-01-01' and '2008-01-01'
order by t1.TRAN_DATE desc
Init
執行計畫
花費時間
A1 Noncluster index(TRAN_DATE) desc
CREATE NONCLUSTERED INDEX nidx_tran_date
ON dbo.QTPLG (TRAN_DATE desc);
A2 Noncluster index(TRAN_DATE) asc
Drop index nidx_tran_date on dbo.QTPLG
CREATE NONCLUSTERED INDEX nidx_tran_date
ON dbo.QTPLG (TRAN_DATE asc);
B1 Cluster index(TRAN_DATE) desc
CREATE CLUSTERED INDEX cidx_tran_date
ON dbo.QTPLG (TRAN_DATE desc);
B2 Cluster index(TRAN_DATE) asc
Drop index cidx_tran_date on dbo.QTPLG
CREATE CLUSTERED INDEX cidx_tran_date
ON dbo.QTPLG (TRAN_DATE asc);
C1 Noncluster index(POLICY_NO) desc
CREATE NONCLUSTERED INDEX nidx_policy_no
ON dbo.QTPLG (POLICY_NO desc);
D1 Cluster index(POLICY_NO) desc
CREATE CLUSTERED INDEX cidx_policy_no
ON dbo.QTPLG (POLICY_NO desc);
D2 Cluster index(POLICY_NO) asc
CREATE CLUSTERED INDEX cidx_policy_no
ON dbo.QTPLG (POLICY_NO asc);
E1 Noncluster index(TRAN_DATE, POLICY_NO) desc
CREATE NONCLUSTERED INDEX nidx_tran_date
ON dbo.QTPLG (TRAN_DATE desc, POLICY_NO desc);
E2 Noncluster index(TRAN_DATE, POLICY_NO) asc
CREATE NONCLUSTERED INDEX nidx_tran_date
ON dbo.QTPLG (TRAN_DATE asc, POLICY_NO asc);
F1 Noncluster index(POLICY_NO, TRAN_DATE) desc
Drop index nidx_tran_date on dbo.QTPLG
CREATE NONCLUSTERED INDEX nidx_policy_no
ON dbo.QTPLG (POLICY_NO desc, TRAN_DATE desc);
G1 Noncluster(TRAN_DATE) include(POLICY_NO) desc
CREATE NONCLUSTERED INDEX nidx_tran_date
ON dbo.QTPLG (TRAN_DATE desc) INCLUDE (POLICY_NO);
G2 Noncluster(TRAN_DATE) include(POLICY_NO) asc
CREATE NONCLUSTERED INDEX nidx_tran_date
ON dbo.QTPLG (TRAN_DATE asc) INCLUDE (POLICY_NO);
H1 Cluster(TRAN_DATE) desc +noncluster(POLICY_NO) desc
CREATE CLUSTERED INDEX cidx_tran_date
ON dbo.QTPLG ([TRAN_DATE] desc)
CREATE NONCLUSTERED INDEX nidx_policy_no
ON dbo.QTPLG (POLICY_NO desc);
GO
H2 Cluster(TRAN_DATE) desc +noncluster(POLICY_NO) asc
CREATE CLUSTERED INDEX cidx_tran_date
ON dbo.QTPLG ([TRAN_DATE] asc)
CREATE NONCLUSTERED INDEX nidx_policy_no
ON dbo.QTPLG (POLICY_NO asc);
GO
I1 Cluster(POLICY_NO)+noncluster(TRAN_DATE) desc
Drop index nidx_policy_no on dbo.QTPLG
Drop index cidx_tran_date on dbo.QTPLG
CREATE CLUSTERED INDEX cidx_policy_no
ON dbo.QTPLG (POLICY_NO desc)
CREATE NONCLUSTERED INDEX nidx_tran_date
ON dbo.QTPLG (TRAN_DATE desc);
GO
I2 Cluster(POLICY_NO)+noncluster(TRAN_DATE) asc
Drop index nidx_policy_no on dbo.QTPLG
Drop index cidx_tran_date on dbo.QTPLG
CREATE CLUSTERED INDEX cidx_policy_no
ON dbo.QTPLG (POLICY_NO asc)
CREATE NONCLUSTERED INDEX nidx_tran_date
ON dbo.QTPLG (TRAN_DATE asc);
GO
結果一覽表
經過上面測試,我們挑選(E和I)效能最好的組合,來測試資料壓縮新技術,看看效能是否會有增長。
(SQL2008企業版才支援資料壓縮)
J1 Row Index Compression
CREATE NONCLUSTERED INDEX nidx_tran_date
ON dbo.QTPLG (TRAN_DATE asc, POLICY_NO asc)
WITH ( DATA_COMPRESSION = ROW ) ;
J2 Row Index Compression
CREATE CLUSTERED INDEX cidx_policy_no
ON dbo.QTPLG (POLICY_NO desc)
WITH ( DATA_COMPRESSION = ROW ) ;
CREATE NONCLUSTERED INDEX nidx_tran_date
ON dbo.QTPLG (TRAN_DATE desc)
WITH ( DATA_COMPRESSION = ROW ) ;
GO
K1 Page Index Compression
CREATE NONCLUSTERED INDEX nidx_tran_date
ON dbo.QTPLG (TRAN_DATE asc, POLICY_NO asc)
WITH ( DATA_COMPRESSION = PAGE ) ;
K2 Page Index Compression
CREATE CLUSTERED INDEX cidx_policy_no
ON dbo.QTPLG (POLICY_NO desc)
WITH ( DATA_COMPRESSION = ROW ) ;
CREATE NONCLUSTERED INDEX nidx_tran_date
ON dbo.QTPLG (TRAN_DATE desc)
WITH ( DATA_COMPRESSION = PAGE ) ;
GO
結果一覽表
結論:
在本測試中,只是大概測試資料壓縮效果,雖然增加查詢和CPU時間,
但資料列壓縮確實有減少一定的IO讀取量和記憶體(剛好型別有支援),
所以還是要有所取捨,對症下藥才可藥到病除。
最後的Index最佳組合
E2:建立非叢集索引,欄位順序為TRAN_DATE、POLICY_NO
CREATE NONCLUSTERED INDEX nidx_tran_date
ON dbo.QTPLG (TRAN_DATE asc, POLICY_NO asc);
Index次佳組合
I1:POLICY_NO建立叢集索引,TRAN_DATE建立非叢集索引
CREATE CLUSTERED INDEX cidx_policy_no
ON dbo.QTPLG (POLICY_NO desc)
CREATE NONCLUSTERED INDEX nidx_tran_date
ON dbo.QTPLG (TRAN_DATE desc);
GO
由此可知,建立Index選擇欄位順序是相當重要的,
請先依Where最右邊開始選擇,其次在包含Select欄位,
如果我選用了E2組合建立Index,也就代表該Table沒有任何叢集索引但也能大大提高效能,
但不管如何決定叢集索引還是非常重要的。