1.1 實現目標
SQL Server 2005 中基於表的分區功能簡化了分區表的創建和維護過程,給數據庫提供了靈活性和更好的性能;如果能良好應用將改善數據庫大型表性能,設計人員管理性的的設計和實現;並方便於DBA相關維護工作
1.2 參考資料
1 微軟msdn
http://www.microsoft.com/china/msdn/library/data/sqlserver/sql2k5partition.mspx?mfr=true
2 WebCasts
SQL Server2005中的表分區功能和索引
http://www.microsoft.com/china/msdn/events/webcasts/shared/webcast/episode.aspx?newsID=1242313
3 sqlserver2005 中文幫助
ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.zh-CHS/tsqlref9/html/f1745145-182d-4301-a334-18f799d361d1.htm
二、 需求描述
2.1主要參與者
2.1.1數據庫管理人員DBA
2.1.2 負責相關模塊的SA
2.2系統相關人員及其興趣
2.2.1 User ,希望系統能快速準確的新增,修改,刪除,查詢,到業務數據;同時因為業務需要和審計需要更多的數據
2.2.2 PM 使管理設計維護功能進一步分開,讓數據庫維護部分交給DBA進行性能調優;同時系統能更好的相應用戶操作;
2.2.3 SA 簡化對數據庫表的設計,並把可以把數據庫設計,可把優化的工作交給DBA處理
2.2.3 Develper 簡化開發工作
2.2.4 DBA減少備份,聚合數據帶來的用戶響應等待;充分利用多硬盤,多CPU能併發處理數據相關工作;利用分區,減能少磁盤I/O讀取;方便實現負載平衡,均衡I/O;建立起良好的數據庫架構工作,方便數據庫服務器性擴展,減少約束和表的結構的維護;
2.3前置條件
2.3.1瞭解基礎環境,包括數據庫,硬件的準備和基本配置情況
數據庫是SQLServer2005 SQL Server Enterprise的版本
硬件 系統是多硬盤,多CPU爲佳
2.3.2現在業務中存在需要性能優化和管理方便的地方
可以優化的有
A. 如何處理 transaction 數據多的 Table
1. 按定時抄去 _Arc 的 database,只留有用(e.g. report要用) 的 data 在 現行的DB
2. 按年份月份 開 Table
上面的方法存在的問題有
每年需要對該表進行定時清理數據,在清理數據的時候會使得該表的索引變得和/或索引變得支離破碎和/或被鎖定,同時處理這些數據的時候將會使系統阻塞的情況,容易使得正常的操作無法正常運行,處理後還需要重修復索引;整個工作比較毫時和影響業務模組的正常運行(雖然可以把這個工作放在週末進行,但是隨着業務數據的增加將會變得龐大)
B 查詢速度由於Data較多的原因,查詢和修改數據比較慢,一次查詢會掃描整個表的數據
2.3.3 DBA需要充分了解分區技術每一個關鍵點; 包括創建,維護方法
2.3.4用SQL PROFILER找出性能存在的瓶頸的SQL
2.4成功後的保證
2.4.1建立分區函數,分區架構,和分區表;
2.4.2 DBA應知道如何維護其架構;
2.4.3 SA瞭解其技術;
2.5基本流程
[描述能夠滿足項目相關人員興趣的典型的成功路徑]
2.5.1確定系統存在的瓶頸問題
2.5.2 確定需要分區的表
2.5.3確定分區鍵和分區數目;
2.5.4建立分區函數,分區架構,分區表;
2.5.5維護分區函數,架構, 分區表
2.5.6在刪除數據和備份中使用分區表
2.6擴展流程(替代流程)
擴展流程主要在,分區表設置前後的對比
2.6.1 查詢成本的比例變化
2.6.2 windows性能檢視器看看對磁盤i/o,和cpu內存變化(能在測試服務器裏測試需要壓力測試才能查看結果)
2.7特殊流程
2.8技術與數據的變化列表
2.9發生頻率
經常
2.10待解決的問題.
2.10.1建立完分區表後,建立不指定分區的聚集索引,可能會導致分區表變成非分區表
2.10.2 如果以DataTime類型做函數區分,可能帶來3微秒的誤差,參考msdn提出
http://www.microsoft.com/china/msdn/library/data/sqlserver/sql2k5partition.mspx?mfr=true
必須更改日期範圍。因爲您要處理的是 datetime 數據,而在時間的存儲方式方面又存在舍入問題,所以必須能夠通過編程方式確定正確的毫秒值。要確定月末最後的 datetime 值,最容易的方法是將正在處理的月份加上 1 個月,然後再減去 2 或 3 毫秒。不能只減去 1 毫秒,因爲 59.999 會上舍入爲 .000,即下個月的第一天。可以減去 2 或 3 毫秒,因爲 2 毫秒將向下舍入爲 .997,而 3 毫秒等於 .997;.997 是可以存儲的有效值。這樣即可確定 datetime 範圍的正確結束值:
三、 系統設計
3.1系統流程設計
建立分區函數,分區架構,分區表,維護分區表結構,數據備份SQL腳本
3.2數據庫設計
先處理StLotLdg表
3.3模塊功能詳細設計
3.3.1建立多個文件組
該步驟是創建數據庫文件分佈到多個磁盤中,以獲取更好的性能(也可以創建在一個磁盤中)
1 創建文件組
ALTER DATABASE DC_CECCS
ADD FILEGROUP [DC_CECCS_FG1]
GO
ALTER DATABASE DC_CECCS
ADD FILEGROUP [DC_CECCS_FG2]
GO
….
2 把文件組加入到驅動器中
INSERT dbo.FilegroupInfo VALUES (1, 1, N'C:/SalesDB')
INSERT dbo.FilegroupInfo VALUES (2, 2, N'D:/SalesDB')
…..
3查看分組信息
創建函數BaseDB..FnPartitionInfo或sql
4 更改文件組語句
ALTER DATABASE Dc_ceccs ADD FILE
5 查看文件組大小
exec sp_helpfile
3.3.2 創建分區表函數,架構,分區表,索引
1創建分區表函數
CREATE PARTITION FUNCTION RangeByMonth (datetime)
注:這裏有 RANGE 和 Left 的方式
更改分區函數爲
2創建分區表架構
CREATE PARTITION SCHEME [SchemeByMonth]
注:可更改分區架構
更改分區架構方式爲:
3 在表中使用分區架構
在sqlserver2000 裏需要手工把數據分別插入不用時間段的表
在sql 2005裏
只要把數據從原表一次插入分區表就可以了,系統自動根據分區函數分別插入數據
(暫不支持直接在原表上創建分區函數)
那麼創建步驟如下:
A先建立一個備份表
創建新表上使用分區表
CREATE TABLE dc_ceccs.[dbo].[ StLotLdgBak] (….) on RangeByMonth
B 再把舊錶數據插入至新表中
use dc_ceccs
SELECT *
INTO StLotLdgbak
FROM StLotLdg
C 刪除舊錶
Drop Table StLotLdg
D 改新表的名稱爲舊錶
sp_rename 'StLotLdgbak1' , 'StLotLdg'
4 查看分區表信息
SELECT $partition.TwoYearDateRangePFN(o.date)
AS [Partition Number]
, min(o. date) AS [Min Order Date]
, max(o. date) AS [Max Order Date]
, count(*) AS [Rows In Partition]
FROM dbo.StLotLdg AS o
GROUP BY $partition.TwoYearDateRangePFN(o. date)
ORDER BY [Partition Number]
GO
5 添加索引
ALTER TABLE StLotLdg
ADD CONSTRAINT StLotLdgPK
PRIMARY KEY CLUSTERED (Date, nvrDocno)
ON SchemeByMonth (Date)
GO
6 使用SQL Server 爲分區表提供的各種連接策略的查詢
SELECT o. nvrDocno, o.Date
FROM dbo.StLotLdg AS o
INNER JOIN dbo.stocklot AS od ON o.lot_no = od. lot_no
WHERE o. Date >= '20050701'
AND o. Date <= '20040930 11:59:59.997'
注,該查詢已經使用到了分區表,不用做整個表的掃描
7 備份數據操作
A備份
exec xp_cmdshell
'bcp "SELECT * FROM StLotLdg WHERE date < ''2006/02/01'' AND date > ''2001/01/01'' " queryout "StLotLdg.txt" -T -c"'
或
備份至本機
或備份至其他表
Create table StLotLdg200601 … on [DC_CECCS_FG1]
在同一個分區裏執行插入數據
INSERT into StLotLdg200601 SELECT * from StLotLdg where date = < '2006/02/01' AND date > '2001/01/01')
插入後建索引
ALTER TABLE [StLotLdg200601]
ADD CONSTRAINT StLotLdg200601PK
PRIMARY KEY CLUSTERED (Date, nvrDocno)
ON [DC_CECCS_FG1]
GO
此時已經使用到分區表,查詢只會進行在相應的歷史分區進行查詢,對現在進行的分區數據影響較小
B刪除原表的數據
truncate table 你的表
或
建立一個作業指定操作時間在晚上進行
while exists (select 1 from StLotLdg where date = < '2006/02/01' AND date > '2001/01/01')
begin
set rowcount 10000
delete StLotLdg where here date = < '2006/02/01' AND date > '2001/01/01' set rowcount 0
end
注 時間可以取 getdate,判斷時間爲 datediff(Year,date,getdate())<=1
C恢復
exec xp_cmdshell
‘bcp dbname.dbo.table_name in d:/ StLotLdg.txt -c -q -S -Usa–P’
或
insert into StLotLdg select * from StLotLdg200601
或
ALTER TABLE StLotLdg SWITCH PARTITION 1
TO OrdersOctober2002
GO
8修改分區表
A 添加一個文件組到數據庫
Use master
GO
ALTER DATABASE Dc_ceccs ADD FILEGROUP DC_CECCS_FG13
GO
ALTER DATABASE Dc_ceccs
ADD FILE
(
NAME = N' DC_CECCS_FG13',FileName = 'D:/Program Files/Microsoft SQL Server/MSSQL.1/MSSQL/DATA/Dc_ceccs13.mdf'
)
TO FILEGROUP DC_CECCS_FG13
GO
Use Dc_ceccs
GO
B 修改分區Scheme
ALTER PARTITION SCHEME RangeByMonthScheme
NEXT USED DC_CECCS_FG13;
GO
C 修改分區函數
ALTER PARTITION FUNCTION RangeByMonth()
SPLIT RANGE ('T/N');
GO