sql server 里的文件和文件组使用

Posted 郭大侠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sql server 里的文件和文件组使用相关的知识,希望对你有一定的参考价值。

转自:https://www.cnblogs.com/woodytu/p/5821827.html

参考:https://www.sqlskills.com/blogs/paul/files-and-filegroups-survey-results/

概要

那么你应该有多少个数据文件和文件组?没有正确的答案,而且甜蜜的地方会因你而异。

一些一般的经验法则:

  • 随着数据库变大,您将更需要多个文件和文件组
  • 多个文件组为您提供增强的可能性,以实现有针对性的灾难恢复,更轻松的可管理性和I / O子系统布局
  • 每个文件组至少应有2-4个文件,tempdb是一种特殊情况

无论您做什么,不要忘记测试以找出工作负载的最佳配置。

在今天的文章里,我想谈下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

-------------向现有数据库添加文件组和文件
--使用sql语句添加文件组和数文件
--向E_Market数据库进行操作
USE E_Market
--添加组FG5
ALTER DATABASE E_Market ADD FILEGROUP FG5 
GO
--为新建的文件组添加数据文件
ALTER DATABASE E_Market ADD FILE
(
name=\'FG5_E_Market_tada\',                                  --数据文件逻辑名称
filename=\'F:\\Prejoct\\FG5_E_Market_tada.ndf\',       --存放位置--辅助数据文件
size=5MB,                                                                --文件初始大小5mb 
FILEGROWTH=10%,                                               --按百分之10增长 
MAXSIZE=500MB                                                     --最大考验增到500mb
)
TO FILEGROUP FG5

 

--将FG5设为默认文件组
ALTER DATABASE E_Market
MODIFY FILEGROUP FG5 DEFAULT
GO

设为默认文件组就是等于在创建文件的时候,默认文件组是为FG5

 

复制代码

把表或索引放到特定的文件组

创建完数据库后,问题是如何把表或索引放到特定的文件组?你可以用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个文件时同样的大小。

  

当你把这些文件放在不同的物理硬盘上,你可以同时访问它们。那就是在一个文件组里有多个文件的强大。

你也可以使用下列脚本获取数据库文件的相关信息。

 

查看数据库文件与文件组信息

--查看数据库文件与文件组信息
SELECT
    name as [database_name],
    COUNT (*) AS [DataFiles],
    COUNT (DISTINCT data_space_id) AS [Filegroups],
    SUM (size)*8/1024 AS [Size(MB)]    --default Kb
FROM sys.master_files
WHERE [type_desc] = N\'ROWS\' -- filter out log files/data_space_id 0
    AND [database_id] > 0  -- filter out system databases
    AND [FILE_ID] != 65537 -- filter out FILESTREAM
GROUP BY [database_id],name;
GO

  

复制代码
-- 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
复制代码

以上是关于sql server 里的文件和文件组使用的主要内容,如果未能解决你的问题,请参考以下文章

小5聊Sql Server基础之Sql语句文件组分区函数分组方案对应分区表的简单步骤

SQL Server - 文件组,文件,备份,分区

SQL Server 文件和文件组

sql SQL为SQL Server创建文件组和文件

SQL Server使用文件组备份降低备份文件占用的存储空间

SQL SERVER删除文件组和文件