您的位置:首页 > 数据库

DBA基础系列SQL Server 2014:2. SQL Server用户数据库初始化配置 推荐

2014-04-27 21:18 381 查看

前言

开始前先黑微软一把:Microsoft秉承一贯的简单易用作风(Next、Next、Next… )这点是它吸引用户的地方,但是这个优点如果用在数据库上将是一场灾难,如我们上一章讲到的SQL Server安装部署,很多人都只知道下一步下一步下一步,但是从来没有考虑过安装向导给出这么多参数配置意义何在,同样的大家习惯了安装完SQL Server后直接使用的方式基本上不去考虑用户数据库初始配置,随着业务量不断攀升,数据量几何倍数的递增,然后发现SQL Server越来越慢,但是又各种无解,最后得出一个结论SQL Server只能满足中小企业需要,但是真实的情况是这样吗?答案当然是否定的【传闻纳斯达克核心数据库原始数据量约2PB现已经转到SQL 2014上了】视频地址
下面我将给到大家一些基本配置和思路让大家的用户数据库在未来数据量增长到TB、PB时依然可以有的放矢的去优化性能满足业务需求
当然这个仅仅是根据我的经验进行探讨,实际情况怎么搭配大家仁者见仁智者见智
无论如何还是要重申一句:本文观点仅代表个人经验,如有不足请大家补充,本文内容如果在实际生产中遇到问题不负任何责任,使用前请先自行论证,最权威的资源请查阅微软官方资料库MSDN,TechNet,官方Blog以及官方技术白皮书等

关于数据库文件

场景一:新建数据库

这种情况进行优化最为轻松,优化成本最低
实施步骤:
1. 业务分析,回答自己几个基本问题:
业务涉及的表:
哪些表是数据活跃表:
哪些是频繁变更表,以哪一类变更为主(INSERT、DELETE 或 UPDATE)

哪些是主要查询的表,数据增量速度

哪些表是数据较活跃表:
这些表数据变化频率多高

这些表数据访问频率多高

涉及到这些表查询的查询速度是什么范围

这些表数据需要保持多久

哪些表是数据惰性表:
这些表数据需要保持多久

这些表每周期增量多少

容量规划:
首先用户数据库至少应该有4个独立的文件组:
主文件组(默认且必须):
建议主文件组数据留空,保持2GB固定大小即可(稍后其他章节再详细讨论保持2GB空的好处)

用户数据文件组(现在存储越来越快建议每文件4GB固定大小):
常规用户数据文件组(至少有一个,通常1-3年或更短):用户数据库存储

分区表文件组(每张分区表建议一个):虽然分区也支持跨多个文件组,但是由于MSSQL与Oracle在分区维护上还是有所不同的(详细的请自行实验体会),所以一般情况每分区表对应一个文件组即可

历史数据文件组(可选,通常3-5年):用于存储近期内需要汇总统计数据

归档数据文件组(可选,通常5-10年):随着存储技术越来越成熟、存储容量越来越大,很多早期需要Offline到磁带备查的数据都可以直接存储到在线数据库中以方便不时只需

用户索引文件组(建议每文件8GB固定大小):
用于存储常规用户数据表对应的非聚集索引

日志文件组(默认且必须:建议单个文件,但是初始值建议要设置大些):
日志文件是串行写入,所以多个日志文件没有任何意义,反而增加文件损坏的风险

日志文件每次扩展都很耗时,同时需要阻塞所有的会话,所以应该尽可能给予一个较大值

P.S. 虽然有资料建议文件数量应该为总CPU Core数的一半,但是这个并不是固定不变的(至少我在实际项目中从来没按这个指导做过),DBA设计文件数量的时候需要考虑:
如何充分利用到多核并行计算能力

如何在一次连续的IO中读取到更多的有效数据

在某文件组存储数据量非常大,其下属的文件也分得很大的时候其一个分解线程去寻找数据的时间或许会比较长(这个问题跟我们不建议数据库采用单一大文件是一样的),还不如多一些文件,虽然访问较多文件会导致线程频繁切换导致开销加重,但是却能缓解在海量数据中寻找有效数据的等待时间,这里又再次体现出了【平衡】两个字的重要

Q/A
Q: 为什么要将常规用户数据、历史数据、归档数据、分区数据、索引数据划分文件组进行分别存储?
A:在文件系统甚至于硬件存储上,我们需要考虑到上述几种数据在IO的寻道规律上的差异充分发挥硬件资源以及如何搭配不同IO性能和价格的存储在满足业务需求的同时将硬件成本降至最低这也是DBA需要考虑的问题
Q:表、文件组与数据文件是什么关系?
A:表存储只在乎文件组是否还有空间,与数据文件没有直接的关系;文件组的存储空间大小=SUM(其下属所有数据文件大小);一个文件组可以包含若干数据文件,一张非分区表只能在一个文件组中(这里只是说的Heap和Clustered Index,而非聚集索引是可以在其它文件组的),一张分区表可以通过分区架构跨越多个文件组
Q:为什么要把数据文件做成固定大小的小文件?
A:为了充分利用多核并行计算能力;为了减少磁盘文件碎片;为了快速的维护存储(Ex:当我们周期性对大表进行归档后会发现文件组一下子腾出很大一块存储空间,这时候如果我希望将这些空闲空间分配给其他文件组使用那么我们需要收缩数据库文件,如果是一个大数据文件我们可能收缩几天都没法达到目标,但是如果通过一个一个地清空小数据文件,再删除空数据文件,我们可以很快释放出有效存储供给更多需求使用)等

场景二:已在使用的数据库

这种情况实际上是早期没有合理规划设计而遗留下来的后遗症,但是我们却需要去解决它【稍微会比较繁琐些】
首先场景一所述我们先创建新的文件组并分配数据文件,然后针对小表进行迁移,针对大表进行分区再导入数据
P.S. 题外话:很多DBA只知道索引需要定期重建,却不知道Heap也要定期重整,不过这给我们实现数据迁移带来了一些好处(Ex:运行了几年的数据库Heap碎片非常的多,表面上可能有100GB,但是重整或迁移以后数据量会缩小一半甚至更多,同时性能会有很大程度的提升)

数据迁移工作:

场景一数据仓库项目:
数据仓库从架构设计到建模,唯一的目标:性能;这也使得我们对数据仓库数据迁移变得方便,因为数据仓库的表没有那么多约束条件、主外键关联等,而且通常事实表我们都需要做分区表,剩下大量的维度表数据量都不会太大;
那么步骤就简单了(特殊情况特殊分析,实施前一定要先去采集和确认元数据中对迁移表的定义)使用以下脚本即可简单完成:
核心思路:
对没有聚集索引的表:创建唯一列,指定新的文件组,创建聚集索引,然后删除聚集索引,最后删除之前创建的唯一列;
已有聚集索引的表:先删掉聚集索引,然后指定新的文件组,创建聚集索引,然后删除聚集索引,最后删除之前创建的唯一列;
以下脚本供参考,不同情况需要不同方式进行修改(写得不好,但是能用,有时间再去优化,God请原谅我又再次情不自禁的使用了游标… … 阿门):
1:  DECLARE @tableName VARCHAR(128)
2:  DECLARE cur CURSORFOR
3:  SELECT  T.NAME
4:  FROM SYS.TABLES T
5:  WHERE
6:  T.OBJECT_ID NOTIN(
7:  (SELECT OBJECT_ID
8:  FROM SYS.INDEXES WHERE INDEX_ID=1  AND IS_PRIMARY_KEY = 1 ))
9:
10:  OPEN cur
11:
12:  FETCHNEXTFROM cur
13:  INTO @tableName
14:
15:  WHILE@@FETCH_STATUS =0
16:  BEGIN
17:  PRINT'
18:      ALTER TABLE ' + @tableName + '
19:      ADD MOVECOLUMN UNIQUEIDENTIFIER NOT NULL
20:      CONSTRAINT CONMOVE DEFAULT NEWID()
21:
22:      ALTER TABLE ' + @tableName + '
23:      ADD  CONSTRAINT [PK_MOVE]
24:      PRIMARY KEY CLUSTERED ( MoveColumn) WITH (ONLINE = OFF) ON [FG_Test_001]
25:
26:      ALTER TABLE ' + @tableName + ' DROP CONSTRAINT CONMOVE
27:
28:      ALTER TABLE ' + @tableName + ' DROP CONSTRAINT [PK_MOVE]
29:
30:      ALTER TABLE ' + @tableName + ' DROP COLUMN MoveColumn
31:
32:      CHECKPOINT
33:
34:      GO'
35:
36:  FETCHNEXTFROM cur
37:  INTO @tableName
38:  END
39:
40:  CLOSE cur
41:  DEALLOCATE cur
将上述T-SQL打印出来的语句Copy到新查询器里面批量执行即可
然后再针对遗留在原始文件组中的那些非聚集索引导出其脚本,批量指定新文件组名字然后DROP,再CREATE
最后原始文件基本上都空了,这时候进行一次数据文件收缩,也就是几秒钟的事情了,至此底层数据整理完成
P.S.其实大家可以看出重整数据文件的过程并不是想象中那么复杂,理清思路产生一大堆脚本,然后扔到Job里面慢慢执行自己就可以提前下班吃饭了
【DBA的工作内容其实还是蛮愉快的:90%以上时间都是在等,等脚本执行,等问题发生,最关键的是等老板发工资;如果一家公司DBA每天都很忙要么是DBA能力不够,要么就是公司或老板有问题】

场景二交易型项目:
交易型项目比数据仓库要复杂一些,不过基本上也是使用上述脚本修修改改就能快速完成
需要注意的地方:主键、外键、约束(尤其是自增约束等)
如果有这些特殊情况就需要有针对性的逐步分析逐步迁移了,这时候就需要先理出一个优先级列表慢慢处理

关于数据库参数

数据库参数也是比较重要的一个环节,尤其是SQL 2000退役,SQL 2005停止主流支持、SQL 2008即将停止主流支持,大量的数据库需要升级到更高版本

数据库兼容级别

在帮助客户进行性能问题分析的时候我留意了一下,很多升级上来的数据库基本上数据库兼容级别都没有修改,这个是需要注意的
SQL Server一般情况默认向下兼容3个主流版本,是为了防止由于版本升级导致用户使用的早期语法或特殊的系统视图出现错误而给予的缓冲机会,并不是说大家在已经升级到高版本后还是继续使用老版本的特性

CHECKSUM

这个参数一般是由于从SQL 2000升级上来时候没有重新配置导致,
SQL 2000的时候还只能简单的检查一下数据页头和定义,无法检查数据页是否真的正常
建议升级上来的所有数据库都去检查一下这个并设置为CHECKSUM



自动维护

自动关闭数据库:这个参数类似于Oracle关闭时仅发出shutdown命令,它会等待所有会话结束后关闭数据库,一般情况我们都会用到immediate要求立即结束和关闭
自动创建统计信息:这个最好是开启,SQL执行依赖的执行计划,执行计划评估执行成本就是根据统计信息来的,所以这个相当重要,不是特殊情况应该保持常开
自动收缩数据库:个人从来就很诧异这个参数,如此耗费性能又没有实际价值的一个参数有存在的意义吗?如果不是特殊原因这个参数应该始终关闭
自动更新统计信息:这个参数同自动创建统计信息是一样的,强烈建议常开,统计信息收集越准SQL执行选择的执行计划就会越优,性能也就越好
自动异步更新统计信息:这个参数建议设置为开启,我们知道统计信息非常重要,但是如果每次数据变化都去收集一次统计信息这个性能也就不那么好了,这个又再次体现了【平衡】



更多优化内容(下一章详解):

以上内容各个版本数据库都适用,下列内容将针对特殊版本使用
数据压缩:
适用版本:SQL Server 2008及其以后
非聚集列存储索引:
适用版本:SQL Server 2012及其以后
聚集列存储索引:
适用版本:SQL Server 2014及其以后
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐