查询sql如何使 SQL Server高效 --T-SQL(ITPUT 讨论汇总)

PS:今天上午,非常郁闷,有很多简略基础的问题搞得我有些迷茫,哎,代码几天不写就忘。目前又不当COO,还是得用心记代码哦!

    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、 在计划数据库操作程序上,您认为应该注意哪些事项,以确保能够有效地应用数据库?

    4、 在您的SQL Server应用进程当中,有哪些令您非常迷惑的性能问题 ?

文章结束给大家分享下程序员的一些笑话语录: 古鸽是一种搜索隐禽,在中国快绝迹了…初步的研究表明,古鸽的离去,很可能导致另一种长着熊爪,酷似古鸽,却又习性不同的猛禽类——犤毒鸟

--------------------------------- 原创文章 By
查询和sql
---------------------------------

posted @ 2013-05-27 19:20  xinyuyuanm  阅读(269)  评论(0编辑  收藏  举报