数据库优化的目标无非是避免磁盘I/O瓶颈、减少CPU利用率和减少资源竞争。
1、 在业务密集的SQL当中尽量不采用IN操作符
2、  不使用not in 因为它不能应用表的索引。用not exists 或(外连接+判断为空)代替
3、  不使用<>,因为用它只会产生全表扫描。(a<>0改为a>0 or a<0)
4、  不使用 is null 或 is not null 判断字段是否为空一般不用到索引。(a is not null 改为a>0)
5、  用a>=3代替a>2,因为a>2时,会先找出a为2的记录索引再进行比较,而a>=3时,会直接找到a=3的索记录引再进行比较。
6、  尽量不使用like %005%(比如前面的%确定在{A,B}内,用A005% or B005%代替%005%)
7、  union在进行表链接后会筛选掉重复的记录。因此会用到排序运算。(若确定没有重复记录的用union all 代替union)
8、  where 条件顺序的影响。(如 select * from T where a=’abc’ and b=1 若a=”abc”在数据库中的记录比b=1在数据库中的记录多,则把b=1放在前面)
9、  尽量避免以下情况:
采用函数处理的字段不能利用索引
进行了显示或隐式运算的字段不能进行索引(把a-5=b 改为a=b+5)
条件内包括多个本表字段不能进行索引
10、合理使用索引,使用索引的原则:
在经常进行连接,但是没有指定为外键的列上建立索引,而不经常连接的字段则由优化器自动生成索引。
在频繁进行排序或分组(即进行group by或order by操作)的列上建立索引。
在条件表达式中经常用到的不同值较多的列上建立检索,在不同值少的列上不要建立索引。(比如在雇员表的“性别”列上只有“男”与“女”两个不同值,因此就无必要建立索引。如果建立索引不但不会提高查询效率,反而会严重降低更新速度。)
如果待排序的列有多个,可以在这些列上建立复合索引(compound index)   
当数据库表更新大量数据后,删除并重建索引可以提高查询速度
11、避免或简化排序:为了避免不必要的排序,就要正确地增建索引,合理地合并数据库表。如果排序不可避免,那么应当试图简化它,如缩小排序的列的范围等
12、消除对大型表行数据的顺序存取:在嵌套查询中,对表的顺序存取对查询效率可能产生致命的影响。比如采用顺序存取策略,一个嵌套3层的查询,如果每层都查询1000行,那么这个查询就要查询10亿行数据。避免这种情况的主要方法就是对连接的列进行索引。例如,两个表:学生表(学号、姓名、年龄……)和选课表(学号、课程号、成绩)。如果两个表要做连接,就要在“学号”这个连接字段上建立索引。
还可以使用并集来避免顺序存取。尽管在所有的检查列上都有索引,但某些形式的where子句强迫优化器使用顺序存取。下面的查询将强迫对orders表执行顺序操作:
SELECT * FROM orders WHERE (customer_num=104 AND order_num>1001) OR order_num=1008
虽然在customer_num和order_num上建有索引,但是在上面的语句中优化器还是使用顺序存取路径扫描整个表。因为这个语句要检索的是分离的行的集合,所以应该改为如下语句:
SELECT * FROM orders WHERE customer_num=104 AND order_num>1001
UNION
SELECT * FROM orders WHERE order_num=1008
这样就能利用索引路径处理查询。
13、避免相关子查询:一个列的标签同时在主查询和where子句中的查询中出现,那么很可能当主查询中的列值改变之后,子查询必须重新查询一次。查询嵌套层次越多,效率越低,因此应当尽量避免子查询。如果子查询不可避免,那么要在子查询中过滤掉尽可能多的行。
14、避免困难的正规表达式(like):这种匹配特别耗费时间。例如:SELECT * FROM customer WHERE zipcode LIKE “98_ _ _” 即使在zipcode字段上建立了索引,在这种情况下也还是采用顺序扫描的方式。如果把语句改为SELECT * FROM customer WHERE zipcode >“98000”,在执行查询时就会利用索引来查询,显然会大大提高速度。
15、使用临时表加速查询:把表的一个子集进行排序并创建临时表,有时能加速查询。它有助于避免多重排序操作,而且在其他方面还能简化优化器的工作。例如:
SELECT cust.name,rcvbles.balance,……other columns
FROM cust,rcvbles
WHERE cust.customer_id = rcvlbes.customer_id
AND rcvblls.balance>0
AND cust.postcode>“98000”
ORDER BY cust.name
如果这个查询要被执行多次而不止一次,可以把所有未付款的客户找出来放在一个临时文件中,并按客户的名字进行排序:
SELECT cust.name,rcvbles.balance,……other columns
FROM cust,rcvbles
WHERE cust.customer_id = rcvlbes.customer_id
AND rcvblls.balance>0
ORDER BY cust.name
INTO TEMP cust_with_balance
然后以下面的方式在临时表中查询:
SELECT * FROM cust_with_balance
WHERE postcode>“98000”
临时表中的行要比主表中的行少,而且物理顺序就是所要求的顺序,减少了磁盘I/O,所以查询工作量可以得到大幅减少。
注意:临时表创建后不会反映主表的修改。在主表中数据频繁修改的情况下,注意不要丢失数据。
16、用排序来取代非顺序存取:在连接列上建立索引。(若非顺序存取表的数据不经常改变,可以建立排序后的临时表,再进行查询。注意:临时表不反映主表的改变。)
17、有大量重复值、且经常有范围查询(between, >,< ,>=,< =)和order by、group by发生的列,可考虑建立群集索引
18、经常同时存取多列,且每列都含有重复值可考虑建立组合索引
19、组合索引要尽量使关键查询形成索引覆盖,其前导列一定是使用最频繁的列
20、注意where字句写法,必须考虑语句顺序,应该根据索引顺序、范围大小来确定条件子句的前后顺序,尽可能的让字段顺序与索引顺序相一致,范围从大到小。
21、尽量使用exists代替select count(1)来判断是否存在记录,count函数只有在统计表中所有行数时使用,而且count(1)比count(*)更有效率
 
22、尽量使用“>=”,不要使用“>”
23、尽可能的使用索引字段作为查询条件,尤其是聚簇索引
24、在使用索引字段作为条件时,如果该索引是联合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用

MSSQL数据库优化经验的更多相关文章

  1. SQL Server数据库优化经验总结

    优化数据库的注意事项: 1.关键字段建立索引. 2.使用存储过程,它使SQL变得更加灵活和高效. 3.备份数据库和清除垃圾数据. 4.SQL语句语法的优化.(可以用Sybase的SQL Expert, ...

  2. 转 : SQL Server数据库优化经验总结

    优化数据库的注意事项: 1.关键字段建立索引. 2.使用存储过程,它使SQL变得更加灵活和高效. 3.备份数据库和清除垃圾数据. 4.SQL语句语法的优化.(可以用Sybase的SQL Expert, ...

  3. [转]SqlSever2005 一千万条以上记录分页数据库优化经验总结【索引优化 + 代码优化】一周搞定

    对普通开发人员来说经常能接触到上千万条数据优化的机会也不是很多,这里还是要感 谢公司提供了这样的一个环境,而且公司让我来做优化工作.当数据库中的记录不超过10万条时,很难分辨出开发人员的水平有多高,当 ...

  4. MS SqlSever一千万条以上记录分页数据库优化经验总结【索引优化 + 代码优化】[转]

    对普通开发人员来说经常能接触到上千万条数据优化的机会也不是很多,这里还是要感谢公司提供了这样的一个环境,而且公司让我来做优化工作.当数据库中的记录不超过10万条时,很难分辨出开发人员的水平有多高,当数 ...

  5. SqlSever2005 一千万条以上记录分页数据库优化经验总结【索引优化 + 代码优化】

    对普通开发人员来说经常能接触到上千万条数据优化的机会也不是很多,这里还是要感谢公司提供了这样的一个环境,而且公司让我来做优化工作.当数据库中的记录不超过10万条时,很难分辨出开发人员的水平有多高,当数 ...

  6. SqlSever2005 一千万条以上记录分页数据库优化经验总结

    http://www.cnblogs.com/jirigala/archive/2010/11/03/1868011.html 待测试???

  7. oracle数据库应用性能优化经验(培训讲义)

    这是我给公司同事做的内部培训ppt的讲义,给大家分享一下.这是培训大纲,ppt在找地方上传,等找到了会把链接发在这里 . 暂时放在csdn上,赚点下载积分:https://download.csdn. ...

  8. 如何判断MSSQL数据库磁盘出现了瓶颈

    问大神石沫:如何判断MSSQL数据库磁盘出现了瓶颈? 石沫(A1):您好,您的问题非常好,SQL SERVER提供了很多关于I/O压力的性能计数器,请选择性能计算器PhysicalDisk(Logic ...

  9. 数据库优化案例——————某市中心医院HIS系统

    记得在自己学习数据库知识的时候特别喜欢看案例,因为优化的手段是容易掌握的,但是整体的优化思想是很难学会的.这也是为什么自己特别喜欢看案例,今天也开始分享自己做的优化案例. 最近一直很忙,博客产出也少的 ...

随机推荐

  1. 完美的代码生成器SNF.CodeGenerator-快速开发者的利器--SNF快速开发平台3.1

    第1章 SNF.CodeGenerator代码生成器简介 本项目是完全基于Spring.Net.Framework 平台进行研发.与Spring.Net.Framework平台无缝衔接.并支持模型层. ...

  2. [APM] 解读APM技术分类和实现方式

    在讲了APM的历史.作用和实际案例之后,下面我们来了解一下APM技术分类和实现方式以及它未来的发展趋势.在这之前,我们首先需要了解一下典型的互联网或移动互联网应用的整个应用交付链. 图1 上面这张示意 ...

  3. golang:mime.Decode、mime.DecodeHeader

    最近在做邮件解析的相关工作,在使用mime.Decode/mime.DecodeHeader时有些疑问. 有些搞不懂mime.Encode和mime.EncodeHeader的区别.

  4. 【30集iCore3_ADP出厂源代码(ARM部分)讲解视频】30-11层驱动之FSMC

    视频简介:该视频介绍iCore3应用开发平台中FSMC通信的配置方法及ARM与FPGA通信的方法. 源视频包下载地址:链接:http://pan.baidu.com/s/1slbHOCH 密码:n06 ...

  5. Socket阻塞模式和非阻塞模式的区别

    简单点说: 阻塞就是干不完不准回来,    非组赛就是你先干,我现看看有其他事没有,完了告诉我一声 我们拿最常用的send和recv两个函数来说吧... 比如你调用send函数发送一定的Byte,在系 ...

  6. Brainfuck反汇编-高级版(Python)

    import re def sym2cal(s): if '>' in s: return len(s) else: return -len(s) def cal(s): if '+' in s ...

  7. RTMP之后,SRT与QUIC

    RTMP协议存在累计延迟与加密方面的问题,为适应互联网视频低延时,高质量的要求,以UDP为核心,具有创造性的SRT,QUIC等流媒体视频方式将成为新的选择 RTMP协议最初是由Macromedia为通 ...

  8. Java如何获取URL连接的日期?

    Java编程中,如何获取URL连接的日期? 以下示例演示如何使用HttpURLConnection类的httpCon.getDate()方法获取URL连接的日期. package com.yiibai ...

  9. circRNA 中的ALU 重复元件

    circRNA 最初研究的很少,只有很小一部分基因有检测到circRNA, 当时都认为是剪切错误形成的,对于其功能也没人去研究:学者对人类的成纤维细胞进行转录组测序,构建去核糖体文库, 同时采用了RN ...

  10. @Autowired注入为null问题分析

    题说明 最近看到Spring事务,在学习过程中遇到一个很苦恼问题 搭建好Spring的启动环境后出现了一点小问题 在启动时候却出现[java.lang.NullPointerException] 不过 ...