如何使 SQL Server高效 — 疑难(ITPUT 讨论汇总)

1、     您认为在设计SQL Server对象时,主要会考虑哪些因素来避免出现性能问题?

讨论汇总——总体设计

应该根据系统架构类型或主要操作进行有针对性的设计: OLTP OLAP ETL

逻辑清晰,使应用程序更便于开发。有良好的扩展性和维护性,减少数据冗余等

DB管理上,得从CPUHDD配置着手,在DB开发上,从业务流程、逻辑、功能、DB结构、SQL指令准确设计和完成目标

设计视图时应针对某个具体需求,不应过多考虑其重用性

触发器也应该避免使用,考虑将触发器完成的功能改写到触发语句中。对于调式,性能跟踪来说,不用触发器也会更直观些

先考虑会出现什么样的性能问题(访问性能?插入性能?);接着考虑数据的变化特点(是小表还是大表?数据的变化频率如何?里面数据重复性如何?),同时也考虑业务特点(是访问多,还是插入多,还是即访问多还有插入多);然后结合SQLServer的原理和特点进行设计,比如要不要使用索引,是使用聚集索引比较好,还是非聚集索引比较好?表的数据要怎么存储才能充分发挥SQL Server的特性(如从SQL Server数据存储、page、碎片等方面考虑。还有要不要使用读写分离?要不要从整个数据库级别也考虑?);最后,考虑对设计完成后的对象,进行测试,然后寻找最优的方案

逻辑数据库和表的设计。数据库的逻辑设计、包括表与表之间的关系是优化关系型数据库性能的核心。一个好的逻辑数据库设计可以为优化数据库和应用程序打下良好的基础。标准化的数据库逻辑设计包括用多的、有相互关系的窄表来代替很多列的长数据表

读写分离架构(如报告数据库和交易数据库部署分离等);关注物理存储;文件布局(数据文件和日志文件隔离,日志文件最好使用高速设备)

考虑数据库规模和重点表的规模,数据库文件组以及内部分区也需要考虑在内,这里可以跟磁盘一起考虑

硬件的二级缓存会影响,把数据、日志、索引放到不同的I/O设备上,增加读取速度。数据量(尺寸)越大,提高I/O越重要.

讨论汇总——表及索引设计

对表的应用场景进行分析,分为日志表、参数表和频繁更新删除表

合理的表数据量估算,分为大表、中表、小表,考虑大表分区/分片

清晰的逻辑和物理模型设计,要准从第三范式,必要时也需要反范式(参考下面的某些场景)

逻辑结构上可以适当冗余,避免太多表关联;物理结构上选择性能高的磁盘策略,表分区,读写分离

设计表对象时首先考虑功能,再考虑性能。如果表中字段过多,考虑拆分对多个小对象(小表);如果表中有访问频率不高,但有需较大存储空间的字段,考虑拆分另外存储

考虑好archive 机制,保证线上业务表数据量不能太大,其余的到历史表,不然SQL Server 单表到亿级别,怎么都不好使

根据业务需求,给各种数据选择恰当的数据类型,节约数据空间的同时提高效率

用占用空间尽量小的数据类型存储数据, date, smalldatetimesmallinttinyint

设计索引时先考虑查询频率和更新频率,切忌为偶尔执行的语句建立索引,建立复合索引时需考虑列的可选择性和使用频率来确定先后顺序

再次对表的索引进行评估(需要应用开发人员的参与,获取其SQL),初步构建索引,从索引列的选择性、索引列的倾斜度,索引列的使用频度、索引列的使用顺序、表索引的个数的综合衡量

索引的效率也很重要,具体要看业务会怎么样去用,设计合理的索引组合,同时需要定期跟踪

创建高效的索引, 使用索引的包含列、过滤索引等功能

讨论汇总——tempdb

,tempdbSQL Server停掉,重启时会自动的drop,re-create. 根据model数据库会默认建立一个新的8MB(mdf file:8MB;ldf file:1MB ecoverymodelsimple

tempdbIO的要求比较高,最好分配到高IO的磁盘上且与其他的数据文件分到不用的磁盘上,以提高读写效率

应该根据根据CPU个数来配置tempdb的文件数(有几个CPU建立几个文件)

个人补充tempdb 的文件初始大小可以设置,通过ALTER DATABASE MODIFY FILE,或者界面操作直接设置文件的初始大小,这个设置在重启SQL服务时,重建tempdb会使用这个设置值

个人补充

合理划分数据库。设计开始的时候就考虑数据库隔离,不要把什么东西都放在一个数据库里面。数据库的划分可以综合考虑这些方面:业务功能、数据重要性、查询和读取比例、数据存储周期

为数据库选择合适的恢复模型(RECOVERY MODEL)。这个对数据库的写入和备份影响比较大

把控需求,明确使用数据库的必要性以及数据存储的详细程度

明确常规字段的定义(特别是在有多个开发团队的情况下),避免因为设计不同,导致在交互(包括相互查询)数据时带来的性能损失

确定合理的对象使用期。有的人喜欢紧密结合当前需求来设计表,结果一段时间之后,可能因为某些变化,不得不修改表结构,修改包含数据的表结构,带来的影响是比较大的;而某些人为了避免这种情况,干脆设计一个非常宽松的表,结果表结构的修改频率可能是非常低了,但是性能可能会受到比较大的影响(比如设计的一些关键字段为了满足未来需要,设计的长度很宽,导致查询性能不好)

争议问题

主键使用自增列

支持使用的观点:

使用系统生成的主键,避免使用复合键,外键总是关联唯一的键字段,不要把社会保障号码(SSN)或身份证号码(ID)选作键

反对使用的观点:

如果一个表可以用自增列作主键,那么这个表的主键可有可无。例如记录网站用户登录信息的日志表。这种表可以不要主键,将登录时间设为聚集索引即可。

GUID生成时需要耗用cpu,也不在考虑范围。当表没有合适的列设主键时,我会考虑固定长度的流水号之类的字段当主键。

不管是自增列、GUID,还是流水号当主键,只要表本身字段有合适的字段作主键,哪怕是复合键,只要长度不太长(100字节以内可考虑,50以内最合适),以及字段数不太多(3个是能接受的范围,5个也可考虑),就应该使用这些字段来当主键。理由是:在表的join以及数据查询中,真正被查询的,还是这些字段。伪主键们除了占用空间,没有一点好处。

如果将一个自增列设为主键,它的好处在哪儿?这样看起来,就是为了给表安一个主键而去create的。你可能会说,自增列当主键,极大减少page spliting,减 少碎片;聚集索引包含在每个非聚集索引的尾部,极大减少索引size等等。我却觉得:1. 一个表的主键,最好能反映出这个表的逻辑设计,意思是,我一看这个表的主键,就大致知道这个表存的什么内容。2:就算你使用了自增列当主键,但实际上这个表的逻辑主键,你还是必须得建立这样的索引。因为数据检索时,往往还是根据这个条件来查询的。自增列的主键,也不会用来当外键,因为它的值极度不靠谱。这样你和别的表关联时,还是仍然需要使用表的逻辑主键字段来关联。所以这样的自增列主键,是多余的,没有必要的

个人的观点:

重点是根据应用场景合理选择,不是绝对的用或不用某种。

对于一个表来说,主键不是必须的,聚焦索引也不是必须的。

从功能上来讲,主键是对表中数据的一种约束(唯一、不允许NULL值),我们通过唯一索引(或约束),并且在字段上设置 NOT NULL属性可以达到同样的效果。所以玉键是可以被取代的,这也说明它不是必需的了(当然,就算没有等同的可取代的功能,从业务上来讲,也并不是每个表都要有一个能够确保数据唯一的东东)。

在提主键的时候,会提聚焦索引,主要是因为主键默认是聚焦索引(如果表中原来没有聚焦索引,并且没有指定NONCLUSTERED的情况下),这表明主键并不是聚焦索引,只是可以把它设置为聚焦索引

所以,单独讨论自增列做主键没有任何意义,我们增加一个自增列,并且把它确认它是唯一和非NULL值的,对于我们的业务数据而言,不存在任何意义(多余和没有必要)。

需要考虑的,是主键作为聚焦索引的情况,当主键为聚焦索引时,我们要考虑的,除了主键的特性外,还要考虑聚焦索引的特性。聚焦索引是和数据存储在一起的,它决定数据的存储顺序,表中数据存储的非叶子层是聚焦索引值(叶子层是数据);另外,聚焦索引键是非聚焦索引的行定位器(指向数据记录的指针,如果聚集索引不是唯一的索引,SQL Server 将添加在内部生成的值(称为唯一值)以使所有重复键唯一。此四字节的值对于用户不可见。仅当需要使聚集键唯一以用于非聚集索引中时,才添加该值)。如果表中没有聚焦索引,那么非聚焦索引的行定位器是指向行的指针(由文件标识符 (ID)、页码和页上的行数生成的行 ID (RID))。很显然,非聚焦索引不依赖聚焦索引,而数据存储我们也并不一定需要保证按照某个顺序来存储,所以聚焦索引也不是必需的。但是从效率上来讲,顺序读取比行ID这种无序读取更有效率,所以对于频繁查询的表,聚焦索引是需要的。

结合前面的信息我们知道,对于可能涉及比较频繁查询的情况,是需要聚焦索引的(确保进行有效的顺序读取);同时我们也知道,聚焦索引键值是非聚焦索引的行定位器(存储在非聚焦索引的叶子层),所以聚焦索引的宽度应该要尽可能小(每个非聚焦索引中都要存一次,当然是越小空间占用越少,I/O效率越高),确保唯一(这样就没有必要为了保证唯一去加那个附加载的值了);另外,NULL值没有比较意义,所以最好是NULL;数据的写入顺序最好是与聚焦索引键值生成顺序差不多,并且频繁的修改尽量不会破坏顺序(这样减少碎片的产生);最后,如果聚焦索引的定义发生修改,那就相当于表和索引都要重新组织存储一次,所以最好的情况是,聚焦索引列定义基本上不会被修改。结合评估这些所有的情况,如果业务数据列是没有合适的,那么自增列会是一个不错的选择。

当然,也有人可能会说,聚焦索引的检索效率是最高的,用自增列做主键,是不是浪费了这个最高效的机会。实际上,这个有点误区,聚焦索引的叶子结点是数据,非聚焦索引的叶子结点是行定位器,这意味着,如果表中的数据不只一列的话,聚焦索引Seek所要加载的页可能比非聚焦索引多(因为它的叶子层是数据,占用的空间比非聚焦索引的行定位器要多),它的好处是SEEK到键值的时候,也就可以直接取出对应的记录了(都在同一页上);而非聚焦索引还要通过行定位器去拿对应的记录;但是如果我们要的数据在索引中就全部包含的话,聚焦索引的效率就可能要低一些了。另外一个就是SCAN的情况,很显然,非聚焦索引涉及的PAGE比聚焦索引少,SCAN会更有优势。不是所有的查询都可以做SEEK,一般查询频繁的表也有多种常用的查询组合,所以总体来说,业务数据列做主键并不是在所有的场景下都能体现出优势。



2、      您认为在T-SQL编写(包括存储过程、函数和视图)上,哪些因素会影响SQL Server效率?

讨论汇总——索引使用

没有索引或者没有用到索引、I/O吞吐量小、没有创建计算列导致查询不优化、锁或者死锁、查询语句不够优化等

对大表而言。那些不走索引的语句,错误scan的语句,还有那些强制使用HINT的语句,可能会因为时间的推移,影响了SQL Server对最优计划的生成

避免无法使用索引的过滤条件。如 WHERE dbo.ufn.Test(ID)=1

确保存在适合查询的索引

根据查询条件,建立索引,优化索引、优化访问方式,限制结果集的数据量。注意填充因子要适当(最好是使用默认值0)。

如果是使用like进行查询的话,简单的使用index是不行的,但是全文索引,耗空间。 like ‘a%’ 使用索引 like ‘%a’ 不使用索引用 like ‘%a%’ 查询时,查询耗时和字段值总长度成正比,所以不能用CHAR类型,而是VARCHAR。对于字段的值很长的建全文索引

讨论汇总——游标:

游标的频繁 / “, 既消耗资源, 同时会给相关的表加

可以通过集合运算的方式去处理数据的情况下,避免使用游标

存储过程通过游标的方式,将函数的功能放在了游标的计算中,这样速度有了一些提高

考虑将游标用其他方式改写(需要验证方法是否有效,无法保证性能的改写,可能比直接使用游标更糟糕),或确保游标高效

个人补充

a)  对于必须逐行处理的情况,建议直接使用游标,如果要避免对构成游标来源数据的影响,可以考虑使用静态游标。对于可以使用集合处理模式替代洲标的情况,也要考虑替代之后的查询复杂性和涉及的数据量,如果这个修改产生的查询非常复杂或涉及大量数据,那么用游标可能可以得到更佳或者更稳定的效果,建议通过测试验证决定最终的方案

b)  注意游标类型的选择

c)  经常使用游标片大量数据量,考虑适当调整cursor threshold选项(异步生成控制)

讨论汇总——临时表与表变量

表变量和临时表的使用要有规定,大小也要有个估计

临时表和内存表要分别对待

个人补充:表变量不受事务控制,其数据写入效率比临时表高;但SQL Server不为表变量生成统计信息,这意味着如果表变量参与查询的话,查询优化器无法评估表变量的数据,从而导致无法有效评估查询方案成本,所以,如果数据需要参与查询的话,始终建议使用临时表(尤其是在复杂查询中,这个非常重要)。另外注意的一点,表变量并不确保只在内存中存在,当数据量大时,其数据仍然会写入tempdb

讨论汇总——综合

存储过程、视图、函数的一个好处是查询计划重用(预先编译)),但还是要注意会导致重编译的操作,例如存储过程中引用和临时表、视图结构更改等

使用不合适的数据类型, 如与表字段不一致, 或发生隐式转换 (字符转数字)

SET NOCOUNT ON , 避免DML操作不必要的网络传输

最典型的函数加于字段上再判断。不正确的实现逻辑将导致性能问题。。当然,这本不属于DB平台的事儿了,是实现者的事儿

编写SQL语句时,在保证完成需要情况下尽量保证SQL简单易读,导致效率抵消的原因有:

a)  过大的事务操作导致事务之间严重阻塞

b)  返回过多无用数据引发磁盘和网络压力

c)  过多的非集合化操作,如在返回列频繁调用某个函数

d)  查询中使用负逻辑

e)  不必要的排序,,查询不需要的数据

f)  冗余的判断逻辑,,多层视图的嵌套引用.

检查不良的SQL,考虑其写法是否还有可优化内容

a)  检查子查询。考虑SQL子查询是否可以用简单连接的方式进行重新书写

b)  考虑数据库的优化器

c)  尽量避免大事务操作, 提高系统并发能力

d)  尽量避免向客户端返回大数据量, 如采用分页

e)  尽量避免游标使用进行大规模数据的连接和遍历

数据库引擎的本身的优化。每个数据库的查询引擎也是在不断进化当中的,有些以前高效的语句现在显得落伍了

.数据库设计优化:在针对不同主题,不同分析方向的时候数据本身的设计结构也会使得SQL语句的写法有所不同

70%性能问题出自不良的SQL语句。条件不符合SAR规范,游标滥用,事务过长,复杂业务逻辑实现追求功能,不考虑性能等等

避免大表的distinct

T-SQL编写要对复杂度进行规定,不能无限制的嵌套或者Union等等。T-SQL中检索数据规模也需要估计

在查询Select语句中用Where字句限制返回的行数,避免表扫描,如果返回不必要的数据,浪费了服务器的I/O资源,加重了网络的负担降低性能。如果表很大,在表扫描的期间将表锁住,禁止其他的联接访问表,后果严重。

存储过程要设计合理,当然提示数据库效率,主要在表的结构和使用合理的查询方法

视图的数据要放在内存中执行,这样才能提升效率,但是要加内存

join的時候要命中index,少用多層嵌套,可以考慮用臨時表

设计SQL后,应使用explain命令检查SQL,看是否使用到索引,是否存在filesort,重点检查检索的行数(rows)是否太大。一般来说.

a)  rows<1000,是在可接受的范围内的。

b)  ows1000~1w之间,在密集访问时可能导致性能问题,但如果不是太频繁的访问(频率低于1分钟一次),又难再优化的话,可以接受,但需要注意观察

c)  rows大于1万时,应慎重考虑SQL的设计,优化SQL,优化db,一般来说不允许频繁运行(频率低于1小时一次)

d)  rows达到10w级别时,坚决不能做为实时运行的SQL。但导数据场合除外,但导数据必须控制好时间,频度

在设计SQL,尤其是稍微复杂的SQL时,一定要在测试环境甚至是实际环境上预先进行explain

SQL语句避免不符合SARS条件的

游标和触发器尽量避免使用

避免长事务,避免出现阻塞和死锁 

复杂逻辑可以多次实现

动态拼接SQL语句是影响SQLServer效率的一个方面

存储过程中多表的连接查询也是影响SQL Server效率的一个方面,当然是许多数据库都具备的毛病,大概是CBO生成执行计划不佳的一个问题,迫不得已多使用临时表

应该采用函数或存储过程代替复杂的视图,性能更好

个人补充:使用自定义函数的时候要注意评估。返回单个值的函数最好能够保障是确定性函数;查询优化器不会为多语句表值函数创建统计信息,所以如果多语句表值函数是用于关联查询的话,可能会产生较差的查询方案

SQL Server没有oracle的非阻塞读,不光是写/写,读/写也会有冲突,应该劲量避免,比如:使用短小事务,合理设置并使用索引,如果可以的话做读写分离;影响SQL瓶颈的因素有很多,包括内存不足,硬件不行,或者没有足够的内存供SQL Server 使用,缺少有用的索引等,网络通讯不好,磁盘配置了,如tempdb 的配置,是否为查询优化器提供了优化复杂查询的最有利条件

个人补充:读写冲突,可以通过控制事务隔离级别(或者相关的表提示)来控制

.数据的量级:在数据量低大的情况下高效率的SQL语句在数据量高的情况下就不能用了,反之亦然

个人补充T-SQL执行包括编译(查询方案评估选择)和执行两个步骤,在查询方案选择的步骤,查询优化器可以根据统计信息、对象结构评估出有效的查询方案,当然,如果查询过于复杂,或者是查询成本评估所需要的信息不准确,评估的结果也会存在误差,所以大部分情况下不会出现需要根据数据量随时调整查询的情况

T-SQL方面SQL Server缺乏Oracle完备的分析函数支持功能,也缺乏一些行列转换、树形目录结构方面的函数,虽然可以通过递归ctexml等函数解决

个人补充:内置函数的多少无法对比,每个数据库都有自己的一些考虑,但常用的基本上是不缺的,对于需要但确实没有的,可以考虑自己写CLR函数。行列转换有 PIVOT UNPIVOT;层次结构有 hierarchyid 数据类型和对应的一些函数

个人补充

复杂查询是需要特别注意控制的。越复杂的查询,意味着可选择的查询方案越多,查询评估所涉及的方面越广,这意味着查询优化器评估查询方案的成本越高,涉及的因素多,意味着评估的方案准确性越低。所以过于复杂的查询,往意味着性能很难保障。了解SQL语句的处理过程,有助于理解这个问题(在联机帮助中搜索“SQL 语句处理)可以得到这方面的说明。另外,要特别注意两种复杂查询:

a)  很多个CTE定义组成的查询。单看每个CTE定义,都很简单,但最终组合起来的,很可能是一个很复杂的查询,可以通过查看执行计划来确定。特别需要注意的是,通过CTE定义将执行步骤写得再清晰和一目了然,最终执行也基本上不是按照写的步骤去做的

b)  视图(包括表值函数)嵌套导致的复杂查询。查询涉及的每个视图可能很简单,但一层层嵌套组合起来,可能最终也形成一个复杂查询,这个也可以勇冠看执行计划确定。(尽量避免在数据库中使用模块化的设计思想)

注意实现方法的控制。比较常见的有下面这些:

a)  使用 JOIN 代替 EXISTS(包括IN)。这种很多时候容易出问题,特别是无法通过结构定义确定JOIN是否会产生一对多之类的情况下。EXISTS只需要考虑是否存在,JOIN还需要考虑数据是一对一,还是一对多或多对多,这两者导致的查询成本评估是不一样的

b)  过多的 IN(值的列表)。这种基本上会被判断为一堆的OR条件,而且会需要评估每个值,很多时候查询成本是比较高的。可以考虑把值先放入临时表,再IN 临时表

c)  减少OR条件。不少的情况下,将OR条件改成多个 UNIONALL的结果会更高效一些

d)  注意条件和JOIN中的数据类型转换。尽可能使用显式的数据类型转换,并将转换的目标放在常量/变量/参数或者数据少的一方。隐式(自动)的数据类型转换是根据类型优先级确定转换目标的,如果转换操作发生在数据量大的一方,那查询就会比较差了




3、     在设计数据库操作程序上,您认为应该注意哪些事项,以确保能够有效地使用数据库?

讨论汇总

尽量缩小读写操作范围和可重复性, 可采用临时表或表变量等中间过程过渡

缓存。在程序端缓存常用数据

)静态化。对应较稳定的数据,可以将它静态化存放,避免数据库访问

)参数化,将访问语句参数化或改为存储过程

连接池,控制访问并并发数

批量处理。将数据修改缓存一段时间后再一起写入数据库

降低事务大小,避免在事务中与用户交互

要应用程序与sql服务器之间做个平衡,哪些计算放在sql服务器,哪些计算放在应用层

个人补充

事务操作尽量放在数据库中控制,避免在程序中控制事务。程序中控制事务不当的话,容易导致使用分布式事务,这种事务方式处理效率比较高,影响它的因素也比较多。另外,程序中控制事务的话,事务锁定资源的释放要在收到程序通知之后,这个稍微加大了资源锁定的时间,并增加了风险因素(比如程序没有及时响应,一些BUG导致事务没有提交或回滚,导致挂起的事务)

特别注意查询参数类型。程序中的数据类型没有数据库中那么严格,所以不少程序员也容易忽略这个问题;数据库中的数据类型是严格的,不匹配就会有数据类型转换,如果这个导致的转换最终是在大量的数据行上,那会产生极大的性能影响

尽量减少程序与数据服务器交互次数,避免无必要的数据传输。比如屏蔽客户端不使用的输出信息、确保没有客户端不关心的查询结果;从DB获取的数据页略大小实际分页(缓存,避免逐页从服务器提取;使用SqlBulkCopy之类的方式在客户端与数据库之间做批量的数据提交




4、     在您的SQL Server使用过程中,有哪些令您非常困惑的性能问题 ?

讨论汇总——综合

Tempdb方面的问题

a)  行级和事务级的快照都存储在TEMPDB (不知架构为什么设计成这样),UNDO \ REDO 自然不太方便

b)  tempdb放了太多的功能,带来性能瓶颈

个人观点 tempdb感觉确实是个瓶颈。每个版本几乎都会往tempdb里面多放一些东西,tempdb所承担的东西是越来越多

配置方面的问题

a)  DBA调整方面能够做的事情不多,内存调整只有2个参数

b)  I/O调整,除了文件级的分离,DBA还能做哪些事情

c)  似乎MSSQL DBA能够做的性能调整就是维护计划,索引优化和统计信息 碎片整理,SQL语句级别调整

d)  内存方面,可控性太少了,划了块大内存后,其他的DBA都干不了了

e)  性能调整方面。MSSQLDBA的空间比较小

个人观点 配置参数的多少这个不太好说,SQL Server还有不少配置项是没有在官方文档上公开说明的;在实际应用中,感觉基本上需要调整的配置项不是太多,不做配置也基本上能够适应大部分情况(自动配置方面做得还是不错);至于DBA的日常工作,只要能够使用合适的方法保障服务器的性能和稳定,并且有合适的措施去预防重复故障的发生就基本达到目标了。至于DB方面是否提供了对应的支持,这个只能具体问题具体分析,有可能是没有提供,也有可能是你没有找到

负载均衡。貌似SQLServer上没什么好的方案吧

个人观点Always on应该算是迈进了一大步,但确实是没有完备的方案

DB LINK,貌似不会走索引,在涉及跨库的时候大数据时,比较纠结

个人观点:会走索引,但限制性比实例内要高;在实例内,查询优化器会尽可能解析对象到基础对象,并获取得评估查询成本相关的信息;对 DB lINK,其获取查询成本评估信息的对象就是查询的对象,如果查询的是表,自然可以获取到相碰的信息,如果不是非索引视图,则是没有索引、统计信息这类对查询成本评估很有帮助的信息可获取,自然就无法走索引

生产环境镜像与复制并存,而mirror的性能似乎不高,经常出现延迟现象,查看wait event,总是镜像方面的等待事件占多

个人观点:可以通过镜像监视器或者镜像相关的动态视图、性能指标,进一步确定延迟的点,以确定可行的改进

千万级大表的排序聚合操作性能尤其低,这方面优化比较困难,目前除了合理索引,大表分区和读写分离建立独立的report server外,没有更好的方法

个人观点:大量数据的聚合应该是要在常规查询中避免的,比如你可以用Job定时把把历史数据聚合写入到聚合表,这样查询只需要聚合未聚合的部分,再UNIONALL已经聚合的数据就可以了;创建包含聚合数据的索引视图,也是一个可行的解决方法(对数据的变更效率会有一定的影响)。另外,通常应该考虑将OLTPOLAP任务分离

发布订阅大并发。大DML量很容易导致死锁,简单的读写分离是我多年心头的痛

个人观点:包含发布的数据库,如果短时间内有表做过大量的数据变更,确实会导致一些问题。复制的日志读取器需要花大量时间去读出这些日志,并提取和生成需要发布的命令;如果被更改的是发布的表,并且分发与发布是共用一个实例的话,分发的压力也会对服务器造成压力;而且复制的命令是记录级(行级)的,所以大量的数据变更的同步周期也会比较长。对于大量数据变更,在可行的情况下,可以考虑勇冠复制存储过程的方式来解决;如果数据变更已经执行,重新同步那些产生了巨大数据变化的表可能是一个解决问题的方法

以前遇到一个情况是,加上forceorder1秒内出结果;去掉force order15

个人观点:可能是统计信息不准,或者是条件包含像变量这种无法确定值的情况,导致查询优化器评估的成本不准

一个SQLInstance下,数据库不断在增加,每个数据库都不太大……长期下去3000个数据库都估计达到的情况下,会不会有性能瓶颈?

个人观点:容易出来性能瓶颈,最常见的可能会是tempdb资源的银用,毕竟每个实例只有一个tempdb,而且很多内部的东东都或多或少会用到tempdb;第2个可能会争用的资源可能是连接资源;另外,管理上可能也会受到影响,比如JobLogin可能会多而且不太容易管理

往往查询最多的表,就是更新最频繁的表。更新最多的字段,也是查询最多的字段。典型的例子是订单表。订单表在不断insert,订单状态字段在不断update。另一方面,订单表在不断被查询,例如当前日期下,已下单未发货的订单详情,已发货未付款的订单详情等等,我们的系统里,这个订单查询界面,都是只要它被打开,就有线程每5秒钟刷新一次最新订单状况。注意每一个客户端每5秒刷新一次。同时在线的用户如果上千个,等于这个表每秒都在刷新了。请问这种情形,大家有什么好的建议?

个人观点:考虑读写分离。另外,考虑程序设计是否合理,比如5秒钏刷新一次的频率是为了100%满足用户需求,1分钟刷新一次是否可以满足90%的需求,如果可以的话,是否一定要满足到100%?手段上,DB数据刷新访问是否可以由一个服务统一控制?如果在同一时间有5个客户端调用这个服务,那么服务只需要取一次数据,分发给5个客户端就行,没必要每个客户端独立去访问DB;更进一步的,是否可以为数据变更设置标志,使用增量的拉数据的方式?

在对很大的表做分区merge操作或者重建索引时, 服务器的cpu使用率很低,,而从sysprocesses中查询到进程的等待类型又是 sos_scheduler_yield,不理解为什么会这样.

个人观点:可以看看各个CPU的任务分配,看是否是因为分配差异太大导致(某一两个CPU使用率高,其他空闲)SELECT scheduler_id , current_tasks_count, runnable_tasks_countFROMsys.dm_os_schedulers WHERE scheduler_id < 255

其他一些SQLserver的时候困扰的因素包括

a)  新版耗内存,CPU处理能力跟不上,磁盘不够大,使得原来旧设备性能到了瓶颈,结果只有一个:退役,更换设备,导致成本增加,设备不能更好的合理利用

b)  新版sqlserver虽然增加了列索引,但也存在索引性能的瓶颈

c)  数据库作业性能瓶颈

d)  低效率的SQL语句导致数据库整体性能降低

e)  T-SQL性能的瓶颈

f)  高并发,需求不稳定,突兀的谷峰交易对数据库和应用的冲击最大

g)  CPU占用率高的现象比较多,降低了又会上去

个人观点:新的东西确实会对硬件有更新的要求,毕竟其设计基础与旧版本是不一样的,根据需要选择合适的版本即可,并不是最新的就一定是最适合的。性能问题,需要一个跟踪分析的过程,确定清楚原因才能找到有效的解决方案

来源:http://blog.csdn.net/zjcxc/article/details/8979756

About 智足者富

http://chenpeng.info

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>