ON PartitionScheme(PartitionColumn),引擎自動路由寫入/讀取對應分區。

**最佳實踐**:每個檔案群組對應一個**獨立物理磁碟/陣列** (如 FG1→SSD, FG2→HDD, FG3→Network Storage),實現 I/O 隔離與成本優化。

PartDB_FG1, PartDB_FG2...E:\Data\PartDB_FG1.ndf、F:\Data\PartDB_FG2.ndf)-- 以 LoginDate (DATETIME) 為分區欄位,按年劃分
CREATE PARTITION FUNCTION PF_LoginDate (DATETIME)
AS RANGE RIGHT FOR VALUES
('2020-01-01', '2021-01-01', '2022-01-01', '2023-01-01');
-- RANGE RIGHT: 邊界值屬於「右側」分區
-- 分區結果:
-- P1: LoginDate < '2020-01-01'
-- P2: '2020-01-01' <= LoginDate < '2021-01-01'
-- P3: '2021-01-01' <= LoginDate < '2022-01-01'
-- P4: '2022-01-01' <= LoginDate < '2023-01-01'
-- P5: LoginDate >= '2023-01-01'

RANGE LEFT vs RIGHT**:LEFT 邊界值屬左側分區 (≤ boundary);RIGHT 邊界值屬右側 (> boundary)。日期類通常用 RIGHT 配合「月初」邊界更直觀。
CREATE PARTITION SCHEME PS_LoginDate
AS PARTITION PF_LoginDate
TO (
FG_2019, -- P1: 2019 以前
FG_2020, -- P2: 2020
FG_2021, -- P3: 2021
FG_2022, -- P4: 2022
FG_2023 -- P5: 2023 及以後
);
-- 檔案群組數量 = 分區數量 (邊界值 N 個 → N+1 個分區)

CREATE TABLE dbo.PartitionTable (
ID INT IDENTITY(1,1) NOT NULL,
Name NVARCHAR(50) NOT NULL,
LoginDate DATETIME NOT NULL -- 分區欄位,必須包含在叢集索引中
)
ON PS_LoginDate(LoginDate); -- 指定分區方案與分區欄位
-- 建立叢集索引 (分區表叢集索引必須包含分區欄位)
CREATE CLUSTERED INDEX CX_PartitionTable_LoginDate
ON dbo.PartitionTable(LoginDate)
ON PS_LoginDate(LoginDate);
SELECT
p.partition_number AS PartitionNum,
f.name AS FileGroup,
p.rows AS RowCount,
prv.value AS BoundaryValue,
CASE pf.boundary_value_on_right WHEN 1 THEN 'RIGHT' ELSE 'LEFT' END AS RangeType
FROM sys.partitions p
JOIN sys.indexes i ON p.object_id = i.object_id AND p.index_id = i.index_id
JOIN sys.data_spaces ds ON i.data_space_id = ds.data_space_id
JOIN sys.filegroups f ON ds.data_space_id = f.data_space_id
JOIN sys.partition_schemes ps ON i.data_space_id = ps.data_space_id
JOIN sys.partition_functions pf ON ps.function_id = pf.function_id
LEFT JOIN sys.partition_range_values prv ON pf.function_id = prv.function_id
AND p.partition_number = prv.boundary_id
WHERE p.object_id = OBJECT_ID('dbo.PartitionTable')
ORDER BY p.partition_number;
INSERT dbo.PartitionTable (Name, LoginDate) VALUES
('User_2019', '2019-06-15'),
('User_2020', '2020-03-22'),
('User_2021', '2021-11-01'),
('User_2022', '2022-07-04'),
('User_2023', '2023-01-15');
-- 查詢各分區行數
SELECT $PARTITION.PF_LoginDate(LoginDate) AS PartitionNum, COUNT(*) AS Cnt
FROM dbo.PartitionTable
GROUP BY $PARTITION.PF_LoginDate(LoginDate);
-- 1. 修改方案:指定下一個分區使用新檔案群組
ALTER PARTITION SCHEME PS_LoginDate NEXT USED FG_2024;
-- 2. 修改函數:分割最後一個分區
ALTER PARTITION FUNCTION PF_LoginDate() SPLIT RANGE ('2024-01-01');
-- 建立同結構暫存表 (同檔案群組) CREATE TABLE dbo.PartitionTable_Archive_2019 ( ... ) ON FG_2019; CREATE CLUSTERED INDEX CX_Archive_2019 ON dbo.PartitionTable_Archive_2019(LoginDate) ON FG_2019; -- 切換分區 1 到暫存表 (元資料操作,毫秒級,無資料移動) ALTER TABLE dbo.PartitionTable SWITCH PARTITION 1 TO dbo.PartitionTable_Archive_2019; -- 現在可對 Archive 表進行備份/壓縮/移動/刪除,完全不影響線上表 DROP TABLE dbo.PartitionTable_Archive_2019; -- 或備份後刪除
ALTER PARTITION FUNCTION PF_LoginDate() MERGE RANGE ('2020-01-01');
| 限制 | 影響 | 對策 |
|---|---|---|
| 分區欄位必須包含在叢集索引鍵中 | 無法在非分區欄位上建立單獨叢集索引 | 叢集索引定義為 (PartitionCol, OtherCols...) |
| 唯一索引/主鍵必須包含分區欄位 | 無法在非分區欄位上建立 PK/Unique Index | PK 定義為 (PartitionCol, ID) 或改用非唯一索引 + 應用層保證 |
| 外鍵不支援跨分區表 | 分區表無法被其他表參考,也無法參考非分區表 | 應用層維護參考完整性,或不使用分區表作為 FK 端 |
| 分區函數/方案修改需鎖定 | SPLIT/MERGE 期間阻塞寫入 | 維護窗口執行,預先 NEXT USED 減少鎖定時間 |
| 統計資訊為表級 | 可能導致特定分區計劃不準 | UPDATE STATISTICS ... WITH FULLSCAN 或 INCREMENTAL = ON (2014+) |
表分區是 SQL Server **大表治理的核心武器**。本文完整演示了:**多檔案群組佈局 → 分區函數 (邊界) → 分區方案 (映射) → 建表指定 → 驗證/切換/滾動窗口** 全生命週期操作。**核心價值**:邏輯上單一表,物理上多檔案群組分佈,實現「冷熱分離、秒級歸檔、維護窗口最小化」。建立前務必評估「查詢模式是否受益於分區裁剪」、「維護複雜度是否可控」。