`

SQL语句执行效率瓶颈

 
阅读更多

影响SQL瓶颈的因素有很多,包括内存不足,硬件不行,或者没有足够的内存供SQL Server 使用,缺少有用的索引等,网络通讯不好,磁盘配置了,如tempdb 的配置,是否为查询优化器提供了优化复杂查询的最有利条件

1.1T-SQL代码返回了不必要的数据

1、缺少WHERE子句,除非你要返回表里所有的数据,而这种情况几乎很少,

在减少返回行的数量时使用WHERE子句是必要的。

例如,如果你仅需返回特定日期的记录,而不是返回月或年的所有记录。设计WHERE语句以便能正好仅仅返回需要的那些行,而不要有额外的行。

2、在SELECT语句里,仅仅包括需要的那些列,而不是所有列。同样,当最可能要返回需要的更多的行时,不是使用SELECT *。

3、引用不必要的数据会产生哪些性能问题:读数据需要额外的I/O开销;浪费缓存空间;产生不必要的网络流量;在客户端,内存不得不存储这些额外的数据,而这部分内存可以被其他应用更好的使用;更重要的是:有时,返回太多的数据会强迫查询优化器执行表扫描而不是索引查找。

1.2在不必要的地方使用了游标

游标一直是一个备受正义的东西,因为游标是过程逻辑,关系模型是基于集合的逻辑。也就是说,游标是要写大量的代码都专注于“如何”处理数据,但是你要使用基于集合的逻辑是,只需要很少的代码。而且这些代码专注于你要获取“什么”而不是如何获取。在需要程序逻辑或便利的情况,每次处理一行的情况下使用游标。例如:给用户发送E-mail,每行都要去调用一个发邮件的存储过程,还有用户订单处理。

定义游标时,如果不是特别需要,使用LOCAL关键显式的将游标定义为局部游标,尽量避免使用全局(GLOBAL,这是数据库的默认行为)游标;没有特殊需要的话,尽量使用FORWA RD_ONLY READ_ONLY STATIC游标;

FORWA RD_ONLY指定游标只能从第一行滚动到最后一行.

注意动态游标的不确定性,动态游标查询的记录集数据如果被修改,会自动刷新游标,这样使得动态游标有了不确定性,因为在多用户环境下,如果其他进程或者本身更改了纪录,就可能刷新游标的记录集。

游标的解决方案基本上都是强制优化器去执行固定的执行计划的,没有基于集合那样优化器会出来很多解决方法然后挑选比较合适的。

在我们的开发过程中游标要慎用,但确实需要逐条处理的时候,那就不用要用其他方案。

例如我们的存储过程中比较常见的一种做法是数据按照顺序放在一个自增的临时表中,然后用循环来处理,实际上这种做法没有游标的方案好。

下面的情况比较适合使用游标来处理(参考demo3__游标1.sql和demo4__游标2.sql)

1.3UNION和UNION ALL使用是否得当

许多人没完全理解UNIONUNIONALL是怎样工作的,因此,结果浪费了大量不必要的SQLServer资源.当使用UNION时,它相当于在结果集上执行UNIONALL。换句话说,UNION将联合两个相类似的记录集,然后搜索潜在的重复的记录并排重。如果这是你的目的,那么使用UNION是正确的。但如果你使用UNION联合的两个记录集没有重复记录,那么使用UNION会浪费资源,因为它要寻找重复记录,即使它们不存在。所以如果你知道你要联合的记录集里没有重复,那么你要使用UNION,而不是UNION。UNION ALL联合记录集,但不搜索重复记录,这样减少。

SQLServer资源的使用,从而全面提升性能。

1.4SELECT DISTINCT使用是否得当

因为DISTINCT子句要求存储结果集然后去重,这样增加SQLServer有用资源的使用。当然,如果你需要去做,那就只有去做了。当如果你知道SELECT语句将从不返回重复记录,那么使用DISTINCT语句对SQLServer资源不必要的浪费。

需要DISTINCT的时候,尽量把它作用在小少的列的上,例如有两个表JOIN,如果DISTINCT作用在一个表上的列已经达到了目的(这个一般从业务上可以确定),那么另一个表的JOIN,在DISTINCT之后才去做(子查询)例:

SELECTDISTINCTa.id,b.name,b.score

FROMtaASaWITH(NOLOCK)

JOINtbbWITH(NOLOCK)

ONa.id=b.id

--改写为

SELECTa.id,b.name,b.score

FROM

(

SELECTDISTINCTidFROMtaWITH(NOLOCK)

)ASas

JOINtbbWITH(NOLOCK)ONa.id=b.id

1.5WHERE子句是可SAGE的吗?

SARG源于"Search ARGument"(搜索参数/ 扫描参数)的首字母拼成

它是指WHERE子句里列和常量的比较。如果SELECT子句是sargable(可SARG的),这意味着它能利用索引加速查询的完成。如果SELECT子句不是可SARG的,这意味着SELECT子句不能利用索引(或

查询1走得是TABLE SCAN 因为,查询分析器预估该查询返回的行数会很多,也就是满足条件的记录站总数的比例比较大,所以会选择TABLE SCAN

查询2 走的是INDEX SEEK因为该查询预估返回的行很少,或者没有结果

查询3 用到了函数,它和2比起来它只能走INDEX SCAN或者TABLE SCAN,所以尽量不要在索引列上使用函数,这样会降低索引的使用率。

比较常见的是使用其实函数如:

WHEREDATEDIFF(DD,adddate,GETDATE())=1

建议改为

WHEREadddate>=CONVERT(VARCHAR(10),GETDATE(),120)

在看下面的语句,已知name的数据类型是VARCHAR

SELECT*FROMtest_objectsWHEREname=N'maxint'

可以看到SQL对此作了数据类型转换,比去掉N多了一个步骤,这种细微的开销会随着数据量的增大或查询的频繁而增加,在SQL SERVER 2008中优化器选择INDEX SEEK,但是在05中它会选择INDEX SCAN

所以在查询的时候要确定等号两边的数据类型一致,在做联接查询的时候尤为重要。

1.6在不必要的时候使用了临时表

1、果语句很复杂,连接太多,可以考虑用临时表和表变量分步完成。

2、需要多次用到一个大表的同一部分数据,考虑用临时表和表变量暂存这部分数据。

3、如果需要综合多个表的数据,形成一个结果,可以考虑用临时表和表变量分步汇总这多个表的数据。

4、他情况下,应该控制临时表和表变量的使用。

5、表和表变量的选择,很多说法是表变量在内存,速度快,应该首选表变量,但是在实际使用中发现,这个选择主要考虑需要放在临时表的数据量,在数据量较多的情况下,临时表的速度反而更快。

6、关于临时表产生使用SELECTINTOCREATETABLE+INSERTINTO的选择,我们做过测试,一般情况下,SELECTINTO会比CREATETABLE+INSERTINTO的方法快很多,但是SELECTINTO会锁定TEMPDB的系统表SYSOBJECTSSYSINDEXESSYSCOLUMNS,在多用户并发环境下,容易阻塞其他进程,所以我的建议是,在并发系统中,尽量使用CREATETABLE+INSERTINTO,而大数据量的单个语句使用中,使用SELECTINTO

1.7存储过程中是否使用了SET NOCOUNT ON

每次存储过程执行时,一个消息会从服务端发给客户端以显示存储过程影响的行数。这些信息对客户端来说很少有用。通过关闭这个缺省值,你能减少在服务端和客户端的网络流量,帮助全面提升服务器和应用程序的性能。在每个存储过程的开头包含SETNOCOUNTON语句


1.8要所有的存储过程的拥有者是DBO吗?引用的形式是databaseowner.objectname吗?

为了最好的性能,同一个存储过程里调用的所有对象的拥有者都应该相同,DBO更适宜。在我们的系统中所有对象的拥有者都是DBO,如果不是那样,即对象名相同而拥有者不同,那么SQLServer必须执行名称判断。当发生这样的情形时,SQLServer不能使用存储过程里在内存里的执行计划,相反,它必须重新编译存储过程,从而影响性能。
当从应用程序里调用存储过程时,使用分隔符名称来调用也是重要的。如:
EXECdbo.myProcedure

代替

EXECmyProcedure

1.9事务的影响范围应该尽可能小

在使用事务时,原则上应该使事务尽可能得短并且要避免事务嵌套。事务应该尽可能得短,这是因为比较长的事务增加了事务占用数据的时间,使其它必须等待访问该事务锁定数据的事务,延长了等待访问数据的时间。在使用事务时,为了使事务尽可能得短,应该采取一些相应的方法,例如,不应该把SELECT放在事务中,因为所有的SELECT都要求使用WITH(NOLOCK),这个放在事务中没有任何意义。一些没有涉及到实体表的操作都放在事物外面。

提高事务中每个语句的效率,利用索引和其他方法提高每个语句的效率可以有效地减少整个事务的执行时间。

尽量不要指定锁类型和索引,SQL SERVER允许我们自己指定语句使用的锁类型和索引,但是一般情况下,SQLSERVER优化器选择的锁类型和索引是在当前数据量和查询条件下是最优的,我们指定的可能只是在目前情况下更优,但是数据量和数据分布在将来是会变化的。

分享到:
评论

相关推荐

    Oracle中SQL语句执行效率的查找与解决

    本文将深入探讨Oracle中SQL语句执行效率的查找与解决方法,特别关注于如何识别和优化那些导致性能瓶颈的查询。 ### Oracle SQL执行效率:查找与解决 #### 一、资源消耗分析 在Oracle中,SQL语句执行效率低下通常...

    ORACLE SQL语句执行效率研究.pdf

    在《ORACLE SQL语句执行效率研究》这篇文章中,作者魏彬深入分析了影响SQL语句执行效率的各种因素,并探讨了提高查询效率的方法。 首先,作者在绪论中提到,随着数据量的增长,SQL语句的效率问题已经成为衡量系统...

    sql server 查看执行效率不高的语句

    因此,掌握如何查看和分析执行效率不高的SQL语句是DBA(数据库管理员)和开发人员必备的技能之一。 SQL Server提供了丰富的DMV(动态管理视图)和系统存储过程,用于监控和诊断数据库的运行状态。其中,`sys.dm_...

    通过分析SQL语句的执行计划优化SQL(总结)

    在数据库管理中,SQL语句的执行效率是关键因素之一,尤其在处理大量数据时。通过对SQL语句的执行计划进行分析,我们可以找到优化查询性能的策略,从而提高数据库系统的整体性能。这篇博客"通过分析SQL语句的执行计划...

    SQL 执行超长语句

    2. **性能瓶颈**:超长SQL语句往往包含大量嵌套查询或条件判断,这会直接影响到查询效率,进而导致系统响应时间延长。 3. **调试困难**:当出现错误时,定位具体问题所在位置变得更加困难。 #### 三、编写高效合理...

    oracle查看执行最慢与查询次数最多的sql语句

    本文将详细介绍如何查看Oracle数据库中执行最慢和查询次数最多的SQL语句,以帮助DBA(数据库管理员)识别潜在的性能瓶颈。 首先,我们来看如何查询执行最慢的SQL语句。在Oracle中,可以使用`v$sqlarea`视图来获取...

    影响sql语句查询效率的因素

    本文将深入探讨影响SQL语句查询效率的关键因素,特别关注查询优化与LIKE语句的使用,帮助数据库管理员和开发人员识别并解决查询性能瓶颈。 ### 影响SQL查询效率的因素 #### 1. **处理NULL值** 当SQL查询涉及对...

    SQL语句执行原理及性能优化.pdf

    影响SQL语句执行效率和性能优化的因素包括但不限于以下几个方面: - 索引的使用:合理地为表中的列创建索引可以大大提高查询的执行速度。 - 查询语句的结构:避免使用全表扫描,减少不必要的列选择,使用连接(JOIN...

    显示 sql 执行效率.

    ### 显示 SQL 执行效率 在数据库管理与优化过程中,SQL 语句的执行效率是至关重要的一个方面。本文将详细介绍如何通过 Oracle 的 SQL*Plus 工具来查看 SQL 语句的执行效率,并手动设置 SQL 语句的执行计划显示方式...

    SQLTracker,抓取sql语句的工具

    4. **可视化展示**:SQLTracker通常会提供直观的图表和统计信息,使用户能快速理解和对比不同SQL语句的执行效率。 5. **性能优化**:通过分析SQLTracker提供的数据,用户可以进行SQL语句的优化,例如调整索引、改进...

    查看LINQ生成SQL语句的几种方法

    Visual Studio的SQL Server Object Explorer工具提供了一个直观的方式来查看连接到的数据库并监视执行的SQL语句。在运行LINQ查询时,可以通过该工具实时查看到生成的SQL。 4. **Entity Framework SQL Server Query...

    Oracle数据库sql语句 跟踪器

    Oracle数据库SQL语句跟踪器,通常被称为SQL Monitor,是一种强大的工具,用于监控和分析数据库中的SQL语句执行情况。在Oracle环境中,理解SQL语句的行为是优化数据库性能的关键。SQL Monitor提供实时视图,帮助DBA...

    idea插件mybaits log 打印sql语句

    标题 "idea插件mybaits log 打印sql语句" 涉及的是一个针对IntelliJ IDEA的MyBatis日志插件,它的主要功能是帮助开发者在开发过程中实时查看并打印出MyBatis执行的SQL语句。这个功能对于调试和优化数据库查询非常...

    压测Oracle的SQL语句的性能情况

    2. **绑定变量**:使用绑定变量可以防止硬解析,提高SQL执行效率,减少解析开销。 3. **执行计划**:通过EXPLAIN PLAN分析SQL执行路径,了解数据库如何处理查询,找出可能导致性能问题的步骤。 4. **索引策略**:...

    浅谈SQL语句的优化对应用程序性能的影响.pdf

    如果应用程序运行缓慢,查询数据时需要长时间等待,问题往往源于数据库端的SQL语句执行效率低下。优化SQL语句可以显著改善这一状况,提高用户体验。 其次,SQL语句消耗的资源通常占数据库资源的70%到90%,特别是在I...

    通过分析SQL语句的执行计划优化SQL语句

    在数据库管理中,SQL语句的执行效率直接影响到系统的性能。优化SQL语句是提升数据库应用性能的关键步骤,尤其在处理大数据量时显得尤为重要。本文将深入探讨如何通过分析SQL语句的执行计划来实现这一目标。执行计划...

    超好用的SQL语句生成及分析器

    在IT行业中,一个优秀的SQL语句生成及分析器可以帮助开发者更高效地编写和优化SQL代码,提高数据库管理效率。本文将详细介绍SQL语句生成及分析器的相关知识点,并结合提供的压缩包文件内容进行解析。 1. SQL语句...

    SQL语句编写好工具

    10. **性能分析**:分析SQL语句的执行计划,帮助找出性能瓶颈,提升查询效率。 “sqlassist_v1.0.70_setup.exe”这个文件名可能是该工具的安装程序,版本号1.0.70表明这是一个较早的版本,可能在后续的更新中增加了...

    SQLtrack 数据库SQL语句监控解析,支持SQL语句追踪 解压直接运行

    SQLtrack能够帮助我们理解SQL语句的执行时间、资源消耗,以及可能存在的瓶颈,这对于性能调优至关重要。通过追踪SQL语句,我们可以识别那些运行慢或者频繁执行的查询,然后进行优化,如创建合适的索引、重构查询语句...

    SQL Server中存储过程比直接运行SQL语句慢的原因

    然而,有时人们发现存储过程的执行速度比直接运行SQL语句要慢,这主要归因于几个因素。 首先,存储过程的编译和缓存机制。存储过程在创建时进行一次性编译,之后的执行会使用已编译的计划,从而避免了每次执行时的...

Global site tag (gtag.js) - Google Analytics