工作中断断续续也写了很多年的SQL了.却总感觉写的是一般的CRUD操作或带些处理逻辑,在高性能、优化方面总不能提高。也google,baidu了一些文章,都是一些基本概念的东西,感觉没有实质性的内容,如:
指定字段,不要用*
适当建索引
只查询需要的数据或分页
用exists代替in
where条件相关处理.......
同时也使用了查询分析器、事件探测器的相关功能:
SET SHOWPLAN_ALL ON --返回每个语句的执行信息
执行计划可以获取开销百分比、I/O开销、CPU开销、运算开销,走了哪个索引....,事件探查器可以获取数据CPU、Reads、Writes、Duration....客户端统计信息里的数据
但不知道对于某条语句来说,这些数据是多少才是正常,达到多少是需要优化??数据库引擎优化顾问不太会用,只知道使用后它推荐您该建哪些索引
向老大提问,同时也希望各位大侠提提意见,讲讲经验,如果有相关的好文章也行
谢过!

解决方案 »

  1.   

    尽少的占cpu,尽少的读io .尽少的让客户等.
    set statistics io on
    set statistics time on
    可以让你看到这些.
      

  2.   


    我的经验是一个查询io读一般少于1000且没有人喊慢,我可以不理.
    cpu执行耗时当然是越小越好,如果大于10s,可能就有人要喊了.
      

  3.   

    精华帖中有两篇关于优化的帖子。要获得参数,可以用typedef来获得各种参数
      

  4.   

    學習.語句優化我深有感受,我們系統的報表只要運行超過1分鐘,user就覺得報表不好,可是數據量太大了.從03年上線到現在已經用了快6年了.數據庫非常的臃腫.
      

  5.   

    SQL Server存储过程编写经验和优化(转)
    http://blog.csdn.net/utpcb/archive/2008/03/17/2191242.aspx浅谈SQL Server查询优化器中的JOIN算法    查询优化器都是支持JOIN操作的,而SQL Server 中主要有以下三类JOIN算法:Nested Loop、Sort-Merge以及Hash Join。尽管每种算法都并不是很复杂,但考虑到性能优化,在产品级的优化器实现时往往使用的是改进过的变种算法。譬如SQL Server 支持block nested loops、index nexted loops、sort-merge、hash join以及hash team。我们在这里只对上述三种基本算法的原型做一个简单的介绍。     【假设】有两张表R和S,R共占有M页,S共占有N页。r 和 s 分别代表元组,而 i 和 j 分别代表第i或者第 j 个字段,也就是后文提到的JOIN字段。     1. Nested Loop Join(嵌套循环联结)     算法:     其思路相当的简单和直接:对于关系R的每个元组 r 将其与关系S的每个元组 s 在JOIN条件的字段上直接比较并筛选出符合条件的元组。写成伪代码就是: foreach tuple r Î R do
      foreach tuple s Î S do
      if ri == sj then add to result     代价:     被联结的表所处内层或外层的顺序对磁盘I/O开销有着非常重要的影响。而CPU开销相对来说影响较小,主要是元组读入内存以后(in-memory)的开销,是 O (n * m)     对于I/O开销,根据 page-at-a-time 的前提条件,I/O cost = M + M * N,翻译一下就是 I/O的开销 = 读取M页的I/O开销 + M次读取N页的I/O开销。     使用小结:     ? 适用于一个集合大而另一个集合小的情况(将小集合做为外循环),I/O性能不错。 
        ? 当外循环输入相当小而内循环非常大且有索引建立在JOIN字段上时,I/O性能相当不错。 
        ? 当两个集合中只有一个在JOIN字段上建立索引时,一定要将该集合作为内循环。 
        ? 对于一对一的匹配关系(两个具有唯一约束字段的联结),可以在找到匹配元组后跳过该次内循环的剩余部分(类似于编程语言循环语句中的continue)。     2. Sort-Merge Join (排序合并联结)     Nested Loop一般在两个集合都很大的情况下效率就相当差了,而Sort-Merge在这种情况下就比它要高效不少,尤其是当两个集合的JOIN字段上都有聚集索引(clustered index)存在时,Sort-Merge性能将达到最好。     算法:     基本思路也很简单(复习一下数据结构中的合并排序吧),主要有两个步骤:     1) 按JOIN字段进行排序 
        2) 对两组已排序集合进行合并排序,从来源端各自取得数据列后加以比较(需要根据是否在JOIN字段有重复值做特殊的“分区”处理)     代价:(主要是I/O开销)     有两个因素左右Sort-Merge的开销:JOIN字段是否已排序 以及 JOIN字段上的重复值有多少。     ? 最好情况下(两列都已排序且至少有一列没有重复值):O (n + m) 只需要对两个集合各扫描一遍 
        ? 最差情况下(两列都未排序且两列上的所有值都相同):O (n * log n + m * log m + n * m) 两次排序以及一次全部元组间的笛卡尔乘积     使用小结:     如前所述,可以考虑在两个结果集都很大情况下使用,最好能有聚集索引保证已经排序完毕。而在实际应用中,我们经常会与遇到的主键-外键关系就是Sort-Merge的一个很好的应用。这种情况下,一般两列都会有聚集索引(已排序)而且一对多的关系保证了至少有一列没有重复值,这种情况下,Sort-Merge的性能是三种里面最好的。     另外,如果要求查询的SQL语法本身就要求GROUP BY、ORDER BY、CUBE等运行,则查询语法整体本来就要做排序,因此可以重用排序结果,此时Merge也是不错的选择。     3. Hash Join (哈希联结)     Hash Join在本质上类似于两列都有重复值时的Sort-Merge的处理思想——分区(patitioning)。但它们也有区别:Hash Join通过哈希来分区(每一个桶就是一个分区)而Sort-Merge通过排序来分区(每一个重复值就是一个分区)。     值得注意的是,Hash Join与上述两种算法之间的较大区别同时也是一个较大限制是它只能应用于等值联结(equality join),这主要是由于哈希函数及其桶的确定性及无序性所导致的。     算法:     基本的Hash Join算法由以下两步组成:     1) Build Input Phase: 基于JOIN字段,使用哈希函数h2为较小的S集合构建内存中(in-memory)的哈希表,相同键值的以linked list组成一个桶(bucket) 
       2) Probe Input Phase: 在较大的R集合上对哈希表进行核对以完成联结。其中核对操作包括: foreach tuple r Î R do
      hash on the joining attribute using the hash function of step 1 to find a bucket in the hash table
      if the bucket is nonempty
      foreach tuple s in the found bucket
      if ri == sj then add to result
        代价:     值得注意的是对于大集合R的每个元组 r ,hash bucket中对应 r 的那个bucket中的每个元组都需要与 r 进行比较,这也是算法最耗时的地方所在。     CPU开销是O (m + n * b) b是每个bucket的平均元组数量。     使用小结:     一般来说,查询优化器会首先考虑Nested Loop和Sort-Merge,但如果两个集合量都不小且没有合适的索引时,才会考虑使用Hash Join。     Hash Join也用于许多集合比较操作,inner join、left/right/full outer join、intersect、difference等等,当然了,需要保证都是等值联结。     另外,Hash Join的变种能够移除重复和进行分组,它只使用一个输入,兼做Build和Probe的角色。     其实产品级的优化器一般都改进了这些基本算法,而改进过的版本的确有较大的性能提升。在这里只是给需要判断执行计划优劣或者研究查询优化器实现的兄弟提供原理方面的介绍,在实际应用中我们还得结合丰富的statistics作出准确的判断。 和尚(hery2002)整理的SQL Server查询优化
    http://topic.csdn.net/u/20080722/21/4501e9cb-a9fa-437e-aaf6-7b629bd26215.html?seed=1110065108
      

  6.   

    haiwer SQL SERVER性能优化综述
    SQL SERVER性能优化综述(http://blog.csdn.net/Haiwer/archive/2008/08/25/2826881.aspx)SQL语句优化汇总(wzy_love_wzy)
    http://topic.csdn.net/u/20080716/11/2317d040-48e7-42da-822e-040b4c55b46d.htmlSQL优化34条
    http://topic.csdn.net/u/20080808/14/dfc973e7-fcf2-4526-9de1-fa5efc148f5c.html
    关于索引优化的文字资料http://topic.csdn.net/u/20090301/19/ef14d61d-53c3-4598-a256-eecd05a5fceb.html对tempdb所做的很多优化都是在透明的情况下,让处理加速:      ◆当临时表被创建的时候,临时表会被缓存起来加速性能。然而,有一些表明确的不会被缓存:  
        ◆关联着显式DDL的临时表  
        ◆关联着命名的约束的临时表  
        ◆作为动态产生的SQL语句的一部分的临时表——例如,存储过程sp_executeSQL的环境中  
        ◆工作表的缓存得到提升。为了节约了空间,会被反复执行的执行计划中的工作表被截短了;现在只有工作表中的前九个页面才会保留。  
        ◆很多其他类型的临时对象也被缓存以提高速度:当在存储过程、函数或者触发器中使用时,表值函数,表变量和局部临时表都会被缓存。对于某种特定的临时对象的编目条目不会被立即丢弃,而是缓存以备将来的重用(一段时间之后,最少使用的对象将从缓存中清除)。  
        ◆对于tempdb中记录的一些修改将不再被记录到日志中,这样可以降低tempdb产生的日志和设备的I/O流量。INSERT操作只会记录插入的记录,DELETE操作只会记录被删除的记录。只有UPDATE操作才会同时记录原值和更新之后的值。(根据Microsoft的内部资料,在此之前的版本,三种操作都会记录操作之前的值和操作之后的值)  
        ◆重新设计tempdb的文件被均衡写入的方式,减少对系统资源的竞争。均衡写入意味着每一个tempdb文件(假设存在多个文件)会被同时写入。因此,如果每个物理文件分散到不同的磁头上,那么对这些文件的写入可以更加有效率的并行处理。建议你为一个SQL Server在每一个CPU创建一个临时文件,并且将每个临时文件放在不同的磁头上。  
        ◆如果一个临时表从tempdb中被丢弃,它会在后台进行处理以降低主机程序的等待时间。实际上,它会被立即处理。      不仅仅是性能,一些变化也影响到了SQL Server 2005的统计收集操作:      ◆SQL Server 2005的动态管理视图(Dynamic Management Views)报告关于tempdb空间使用情况的统计数据,可以通过查询检索到这些数据。例如,SELECT SUM (unallocated_extent_page_count)*8 as [Free Space] FROM sys.dm_db_file_space_usage会返回tempdb文件中以kilobytes计算的自由空间总数。  
        ◆Trace标志TF-1118(表示分配整个的extents给每个tempdb对象)已经被重新改造,减少资源的竞争。你可以用它作trace检查而不用担心对tempdb性能产生影响。  
        ◆两个新的性能指标,临时表新建率(Temp Tables Creation Rate)和临时表销毁计数(Temp Tables for Destruction),在SQL Server 2005中出现。它们分别指示每秒钟新建多少个临时表和多少个临时表在排队销毁。      这些变化可以让程序员对tempdb实际的运行方式有一些洞察,而不是被它表面上的行为所蒙蔽——毫无疑问,一个创新的程序员可以利用这些来写出更好的、更先进的SQL Server 2005代码。 
      

  7.   

    谢谢perfectaction、HEROWANG、dawugui 
    谢谢大家继续学习,继续关注....
      

  8.   

    122wo呵122wo呵122wo呵122wo呵122wo呵
      

  9.   

    SQL效率,我也很差劲。
    学习