1. 程式人生 > 實用技巧 >SQL SERVER 表分割槽測試備忘

SQL SERVER 表分割槽測試備忘

  最近遇到一個反饋說系統查詢很慢,經常發生超時的問題,因系統上線比較久,部分資料表資料量比較大,常用的表少則1千多萬,多的超過1億條資料,且都是常用的表。目前想到的方案有:

  1. 分庫:報表查詢用一個庫,操作用一個庫。這樣的改動對於系統來說改動比較小,但基本無法解決超時的問題;
  2. 分表:對於報表的改動比較大,是一個備選方案;
  3. 表分割槽:看到有文章介紹說表分割槽可解決效能問題,因表分割槽不需要對業務程式碼做任何改變,基於此特性我做了個驗證。

  關於表分割槽的操作過程可參考:SQL Server表分割槽

  如果需要調整表分割槽方案可參考:SQL修改表分割槽方案(高效)

  本次我在本機上做新建一個測試庫,並建立了 5千萬條資料,分5個表分割槽檔案測試,每個檔案1千萬條資料。

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[pro_main](
    [prohid] [BIGINT] IDENTITY(1,1) NOT NULL,
    [barcodeid] [VARCHAR](50) NOT NULL,
    [createdate] [DATETIME] NOT NULL,
    [sortid] [INT] NOT NULL,
    [userid] [INT] NOT NULL,
    [realname] [VARCHAR](50) NULL,
 
CONSTRAINT [PK_pro_main] PRIMARY KEY CLUSTERED ( [prohid] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ) GO DECLARE @i BIGINT; SET @i = 1; WHILE (@i <= 5000000) BEGIN INSERT INTO dbo.pro_main ( barcodeid, createdate, sortid, userid, realname )
VALUES (NEWID(), GETDATE(), @i,3421, 'gaobaosong'+ CAST(@i AS VARCHAR(10))); SET @i = @i + 1; END; GO
建立測試資料

  用如下程式碼驗證資料分佈:

-- fn_main 為分割槽函式
SELECT COUNT(1) 數量, $partition.fn_main(prohid) 分割槽號 
FROM dbo.pro_main
GROUP BY $partition.fn_main(prohid)
檢視資料分佈

  資料分佈都符合預期。下面我將表分割槽和不做表分割槽對比著查詢,看下實際效能如何。

-- 釋放快取
DBCC FREEPROCCACHE
DBCC FREESESSIONCACHE

-- 表分割槽的
SELECT $partition.fn_main(prohid) fc, * 
FROM dbo.pro_main WHERE barcodeid LIKE '%3752c%'

-- 未做表分割槽的
SELECT * 
FROM dbo.pro_main01 WHERE barcodeid LIKE '%3752c%'
查詢對比

  通過查詢分析對比,他們的速度幾乎一致,有做過分割槽的甚至比未做分割槽的查詢要慢。但加上了查詢的分割槽號後表分割槽的查詢速度立馬體現出來了。

SELECT $partition.fn_main(prohid) fc, * 
FROM dbo.pro_main WHERE barcodeid LIKE '%3752c%' 
    AND $partition.fn_main(prohid) BETWEEN 2 AND 3
在分割槽中查詢

  

  結論:

  1. 有文章介紹的說表分割槽查詢速度快是有前提的,即限定在某個分割槽的查詢速度會快;
  2. 在應對大體量資料的時候,表分割槽在某些場景下可能有用,但它不是萬能的。