在现在互联网应用程序开发过程中,常常会发现查询或者操作数据速度慢。其原因很多,常见如下几种:
1、没有索引或者没有用到索引(这是数据库设计的缺陷)
2、I/O吞吐量小,形成了瓶颈效应。
3、内存不足
4、网络速度慢
5、查询出的数据量过大(可以采用多次查询)
6、锁或者死锁(这也是程序设计的缺陷)
7、返回了不必要的行和列
8、查询语句不好,没有优化
数据库要高效运行,首先要保证数据库设计的正确性,非特殊需要不要违反三大范式原则;然后再来考虑数据库性能及效率的优化工作。日常工作中,我们经常用到的一些优化方法如下:
1、把数据、日志、索引放到不同的I/O设备上,增加读取速度。数据量(尺寸)越大,提高I/O越重要。
2、升级硬件。
3、根据查询条件,建立索引,优化索引、优化访问方式,限制结果集的数据量。索引应该尽量小,使用字节数小的列建索引好,不要对有
限的几个值的字段建单一索引。
4、查询耗时和字段值总长度成正比,所以数据库设计的时候可变长字段不能用CHAR类型,而是VARCHAR。有相当一部份开发人员喜欢可变长字符串也用CHAR,然后补空格。
5、重建索引DBCC REINDEX,DBCC INDEXDEFRAG,收缩数据和日志 DBCC SHRINKDB,DBCC SHRINKFILE。设置自动收缩日志。对于大的数据库不要设置数据库自动增长,它会降低服务器的性能。
6、在查询Select语句中用Where字句限制返回的行数,避免表扫描。如果返回不必要的数据,浪费了服务器的I/O资源,加重了网络的负担降低性能。如果表很大,在表扫描的期间将表锁住,禁止其他的联接访问表,后果严重。
7、尽可能不使用光标,它占用大量的资源。如果需要row-by-row地执行,尽量采用非光标技术,如:在客户端循环,用临时表,Table变量,用子查询,用Case语句等等。
8、用Profiler来跟踪查询,得到查询所需的时间,找出SQL的问题所在;用索引优化器优化索引。
9、注意UNion和UNion all 的区别。尽量使用UNION all。
10、注意使用DISTINCT,在没有必要时不要用,它同UNION一样会使查询变慢。
11、查询时不要返回不需要的行、列
12、用select top 100 / 10 Percent 来限制用户返回的行数或者SET ROWCOUNT来限制操作的行。
13、使用查询分析器,查看SQL语句的查询计划和评估分析是否是优化的SQL。一般的20%的代码占据了80%的资源,我们优化的重点是这些慢的地方。
14、如果使用了IN或者OR等时发现查询没有走索引,使用显示申明指定索引: Select * FROM tablename (INDEX = IX_Title) Where sex IN ('男','女')
15、数据库有一个原则是代码离数据越近越好,所以优先选择Default,依次为规则、触发器、约束Constraint(约束如外健主健CheckUNIQUE……,数据类型的最大长度等等都是约束)、存储过程。这样不仅维护工作小,编写程序质量高,并且执行的速度快。
16、如果要插入大的二进制值到Image列,使用存储过程,千万不要用内嵌Insert来插入。因为应用程序首先将二进制值转换成字符串(尺寸是它的两倍),服务器受到字符后又将他转换成二进制值。存储过
程就没有这些动作。方法:Create procedure p_insert as insert into table(Fimage) values (@image), 在前台调用这个存储过程传入二进制参数,这样处理速度明显改善。
17、Between在某些时候比IN 速度更快,Between能够更快地根据索引找到范围。用查询优化器可见到差别。 select * from chineseresume where title in ('男','女')和Select * from chineseresume where between '男' and '女' 是一样的功能。由于in会在比较多次,所以有时会慢些。
18、不要在程序中使用没有作用的事务处理。
19、用OR的字句可以分解成多个查询,并且通过UNION 连接多个查询。他们的速度只同是否使用索引有关,如果查询需要用到联合索引,用UNION all执行的效率更高。多个OR的字句没有用到索引,改写成UNION的形式再试图与索引匹配。一个关键的问题是否用到索引。
20、尽量少用视图,它的效率低。对视图操作比直接对表操作慢,可以用stored procedure来代替它。特别的是不要用视图嵌套,嵌套视图增加了寻找原始资料的难度。
21、没有必要时不要用DISTINCT和ORDER BY,这些动作可以改在客户
端执行。它们增加了额外的开销。这同UNION 和UNION ALL一样的道理。
22、在IN后面值的列表中,将出现最频繁的值放在最前面,出现得最少的放在最后面,减少判断的次数。
23、一次更新多条记录比分多次更新每次一条快,就是说批处理好。
24、尽量将数据的处理工作放在服务器上,减少网络的开销,如使用存储过程。存储过程是编译好、优化过、并且被组织到一个执行规划里、且存储在数据库中的SQL语句,是控制流语言的集合,速度当然快。
25、通过SQL Server Performance Monitor监视相应硬件的负载 Memory: Page Faults / sec计数器如果该值偶尔走高,表明当时有线程竞争内存。如果持续很高,则内存可能是瓶颈。
本文转自 netcorner 博客园博客,原文链接: http://www.cnblogs.com/netcorner/archive/2007/10/20/2912278.html ,如需转载请自行联系原作者