SQL Server里的文件和文件组

在今天的文章里,我想谈下SQL Server里很是重要的话题:SQL Server如何处理文件的文件组。当你用CREATE DATABASE命令建立一个简单的数据库时,SQL Server为你建立2个文件:web

  • 一个数据文件(.mdf)
  • 一个事务日志文件(.ldf)

数据文件自己在有且只有一个主文件组里建立。默认状况下,在主文件组里,SQL Server存储素有的数据(用户表,系统表等)。那有额外的文件和文件组的目的是什么?咱们来看下。算法

多个文件组

当你为你的数据建立额外的文件组,你能够在它们里面存储你定义的表和索引,这个会在多个方面帮助你sql

  • 你能够保持你的主文件组很小。
  • 你能够把你的数据分割到多个文件组(例如,你能够在企业版里使用文件分区)。
  • 你能够在文件组级别进行备份和还原操做。这给你在你的备份和还原策略上更多细粒度的控制。
  • 你能够在文件组级别运行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命令来完成这个任务。 spa

-- 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关键字的文件组里。code

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

这是我一般推荐的方法,由于你不须要再考虑,在建立完你的数据库对象后。所以如今让咱们建立一个新的表,它会自动存储在FileGroup1文件组。orm

-- 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

小结

在今天的文章里我向你展现了多个文件组和文件组里多个文件是如何让你的数据库更容易管理,还有文件组里的多个文件是如何使用轮询调度分配算法。

感谢关注!

参考文章

https://www.sqlpassion.at/archive/2016/08/29/files-and-file-groups-in-sql-server/

相关文章
相关标签/搜索