1. 程式人生 > >SQL Server如何處理檔案的檔案組

SQL Server如何處理檔案的檔案組

在今天的文章裡,我想談下SQL Server裡非常重要的話題:SQL Server如何處理檔案的檔案組。當你用CREATE DATABASE命令建立一個簡單的資料庫時,SQL Server為你建立2個檔案:

  • 一個數據檔案(.mdf)
  • 一個事務日誌檔案(.ldf)

資料檔案本身在有且只有一個主檔案組裡建立。預設情況下,在主檔案組裡,SQL Server儲存素有的資料(使用者表,系統表等)。那有額外的檔案和檔案組的目的是什麼?我們來看下。

多個檔案組

當你為你的資料建立額外的檔案組,你可以在它們裡面儲存你定義的表和索引,這個會在多個方面幫助你

  • 你可以保持你的主檔案組很小。
  • 你可以把你的資料分割到多個檔案組(例如,你可以在企業版裡使用檔案分割槽)。
  • 你可以在檔案組級別進行備份和還原操作。這給你在你的備份和還原策略上更多細粒度的控制。
  • 你可以在檔案組級別執行DBCC CHECKDB命令,而不是資料庫級別。

通常,你應該至少有一個從檔案組,這裡你可以儲存你自己建立的資料庫物件。你不應該在主檔案組裡儲存SQL Server為你建立的其他系統物件。

多個檔案

當你建立了你自己的檔案組,你也要至少放一個檔案進去。另外,你可以增加額外的檔案到檔案組。這也會提高你的負荷效能,因為SQL Server會散步資料在所有的檔案間,即所謂的輪詢排程分配演算法(Round Robin Allocation Algorithm)。

第一個64K在第一個檔案儲存,第二個64k在第二個檔案儲存,第三個區在第一個檔案儲存(在你的檔案組裡,你有2個檔案時)。

使用這個方法,SQL Server可以在緩衝池裡閂鎖分配點陣圖頁(PFS,GAM,SGAM)的多個副本,並提高你的負荷效能。你也可以用這個方法解決在TempDb裡預設配置的同個問題。另外,SQL Server也會確保檔案組的所有檔案在同一時間點滿——通過所謂的比例填充演算法(Proportional Fill Algorithm)。因此,在檔案組裡你的所有檔案有同樣的初始大小和自動增長引數非常重要。不然輪詢排程分配演算法就不能正常工作。

例項演示

現在我們來看下一個例項,如何建立額外檔案組裡有多個檔案在裡面的資料庫。下列程式碼展示了你必須用到的CREATE DATABASE命令來完成這個任務。

-- Create a new database
CREATE DATABASE MultipleFileGroups ON PRIMARY
(
    -- Primary File Group
    NAME = 'MultipleFileGroups',
    FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL11.SQL2012\MSSQL\DATA\MultipleFileGroups.mdf',
    SIZE = 5MB,
    MAXSIZE = UNLIMITED,
    FILEGROWTH = 1024KB
),
-- Secondary File Group
FILEGROUP FileGroup1
(
    -- 1st file in the first secondary File Group
    NAME = 'MultipleFileGroups1',
    FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL11.SQL2012\MSSQL\DATA\MultipleFileGroups1.ndf',
    SIZE = 1MB,
    MAXSIZE = UNLIMITED,
    FILEGROWTH = 1024KB
),
(
    -- 2nd file in the first secondary File Group
    NAME = 'MultipleFileGroups2',
    FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL11.SQL2012\MSSQL\DATA\MultipleFileGroups2.ndf',
    SIZE = 1MB,
    MAXSIZE = UNLIMITED,
    FILEGROWTH = 1024KB
)
LOG ON
(
    -- Log File
    NAME = 'MultipleFileGroups_Log',
    FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL11.SQL2012\MSSQL\DATA\MultipleFileGroups.ldf',
    SIZE = 5MB,
    MAXSIZE = UNLIMITED,
    FILEGROWTH = 1024KB
)
GO

建立完資料庫後,問題是如何把表或索引放到特定的檔案組?你可以用ON關鍵字人為制定檔案組,如下程式碼所示:

CREATE TABLE Customers
(
   FirstName CHAR(50) NOT NULL,
   LastName CHAR(50) NOT NULL,
   Address CHAR(100) NOT NULL,
   ZipCode CHAR(5) NOT NULL,
   Rating INT NOT NULL,
   ModifiedDate DATETIME NOT NULL,
)
ON [FileGroup1]
GO

另一個選項,你標記特定檔案組為預設檔案組。然後SQL Server自動建立新的資料庫物件在沒有指定ON關鍵字的檔案組裡。

-- FileGroup1 gets the default filegroup, where new database objects
-- will be created
ALTER DATABASE MultipleFileGroups MODIFY FILEGROUP FileGroup1 DEFAULT
GO

這是我通常推薦的方法,因為你不需要再考慮,在建立完你的資料庫物件後。因此現在讓我們建立一個新的表,它會自動儲存在FileGroup1檔案組。

-- The table will be created in the file group "FileGroup1"
CREATE TABLE Test
(
    Filler CHAR(8000)
)
GO

現在我們進行簡單的測試:我們插入40000條記錄到表。每條記錄8K大小。因此我們插入了320MB資料到表。這是我剛才提的輪詢排程分配演算法,會進行操作:SQL Server會在2個檔案間發放資料:第一個檔案有160M的資料,第二個檔案也會有160M的資料。

-- Insert 40.000 records, results in about 312MB data (40.000 x 8KB / 1024 = 312,5MB)
-- They are distributed in a round-robin fashion between the files in the file group "FileGroup1"
-- Each file will get about 160MB
DECLARE @i INT = 1
WHILE (@i <= 40000)
BEGIN
    INSERT INTO Test VALUES
    (
        REPLICATE('x', 8000)
    )
    
    SET @i += 1
END
GO

接下來你可以在硬碟上看下,你會看到2個檔案時同樣的大小。

當你把這些檔案放在不同的物理硬碟上,你可以同時訪問它們。那就是在一個檔案組裡有多個檔案的強大。

你也可以使用下列指令碼獲取資料庫檔案的相關資訊。

-- Retrieve file statistics information about the created database files
DECLARE @dbId INT
SELECT @dbId = database_id FROM sys.databases WHERE name = 'MultipleFileGroups'

SELECT 
    sys.database_files.type_desc, 
    sys.database_files.physical_name,
    sys.dm_io_virtual_file_stats.* FROM sys.dm_io_virtual_file_stats
(
    @dbId,
    NULL
)
INNER JOIN sys.database_files ON sys.database_files.file_id = sys.dm_io_virtual_file_stats.file_id
GO

小結

在今天的文章裡我向你展示了多個檔案組和檔案組裡多個檔案是如何讓你的資料庫更容易管理,還有檔案組裡的多個檔案是如何使用輪詢排程分配演算法。