Wednesday, September 22, 2010

解决/优化SQL Server查询速度慢的方法

1、把数据、日志、索引放到不同的I/O设备上,增加读取速度,以前可以将Tempdb应放在RAID0上,SQL2000不在支持。数据量(尺寸)越大,提高I/O越重要。
2、纵向、横向分割表,减少表的尺寸(sp_spaceuse)
3、升级硬件
4、根据SQL Server查询条件,建立索引,优化索引、优化访问方式,限制结果集的数据量。注意填充因子要适当(最好是使用默认值0)。索引应该尽量小,使用字节数小的列建索引好(参照索引的创建),不要对有限的几个值的字段建单一索引如性别字段。
5、提高网速。
6、扩大服务器的内存,Windows 2000和SQL server 2000能支持4-8G的内存。
配置虚拟内存:虚拟内存大小应基于计算机上并发运行的服务进行配置。运行 Microsoft SQL Server? 2000时,可考虑将虚拟内存大小设置为计算机中安装的物理内存的1.5倍。如果另外安装了全文检索功能,并打算运行Microsoft搜索服务以便执行 全文索引和SQL Server查询。
可考虑:将虚拟内存大小配置为至少是计算机中安装的物理内存的3倍。将SQL Server max server memory服务器配置选项配置为物理内存的1.5倍(虚拟内存大小设置的一半)。
7、增加服务器CPU个数;但是必须 明白并行处理串行处理更需要资源例如内存。使用并行还是串行程是MsSQL自动评估选择的。单个任务分解成多个任务,就可以在处理器上运行。例如耽搁查询 的排序、连接、扫描和GROUP BY字句同时执行,SQL SERVER根据系统的负载情况决定最优的并行等级,复杂的需要消耗大量的CPU的查询最适合并行处理。但是更新操作UPDATE,INSERT, DELETE还不能并行处理。
8、如果是使用like进行查询的话,简单的使用index是不行的,但是全文索引,耗空间。 like ''a%'' 使用索引 like ''%a'' 不使用索引用 like ''%a%'' 查询时,SQL Server查询耗时和字段值总长度成正比,所以不能用CHAR类型,而是VARCHAR。对于字段的值很长的建全文索引。
9、DB Server 和APPLication Server 分离;OLTP和OLAP分离
10、分布式分区视图可用于实现数据库服务器联合体。
联合体是一组分开管理的服务器,但它们相互协作分担系统的处理负荷。这种通过分区数据形成数据库服务器联合体的机制能够扩大一组服务器,以支持大型的多层 Web 站点的处理需要。有关更多信息,参见设计联合数据库服务器。(参照SQL帮助文件''分区视图'')
a、在实现分区视图之前,必须先水平分区表
b、 在创建成员表后,在每个成员服务器上定义一个分布式分区视图,并且每个视图具有相同的名称。这样,引用分布式分区视图名的查询可以在任何一个成员服务器上 运行。系统操作如同每个成员服务器上都有一个原始表的复本一样,但其实每个服务器上只有一个成员表和一个分布式分区视图。数据的位置对应用程序是透明的。
11、重建索引 DBCC REINDEX ,DBCC INDEXDEFRAG,收缩数据和日志 DBCC SHRINKDB,DBCC SHRINKFILE. 设置自动收缩日志.对于大的数据库不要设置数据库自动增长,它会降低服务器的性能。
在T-sql的写法上有很大的讲究,下面列出常见的要点:首先,DBMS处理SQL Server查询计划的过程是这样的:
1、 查询语句的词法、语法检查
2、 将语句提交给DBMS的查询优化器
3、 优化器做代数优化和存取路径的优化
4、 由预编译模块生成SQL Server查询规划
5、 然后在合适的时间提交给系统处理执行
6、 最后将执行结果返回给用户。
其次,看一下SQL SERVER的数据存放的结构:一个页面的大小为8K(8060)字节,8个页面为一个盘区,按照B树存放。

12、 Commit和rollback的区别 Rollback:回滚所有的事物。 Commit:提交当前的事物. 没有必要在动态SQL里写事物,如果要写请写在外面如: begin tran exec(@s) commit trans 或者将动态SQL 写成函数或者存储过程。
13、在查询Select语句中用Where字句限制返回的行数,避免表扫描,如果返回不必要的数据,浪费了服务器的I/O资源,加重了网络的负担降低性能。如果表很大,在表扫描的期间将表锁住,禁止其他的联接访问表,后果严重。
14、SQL的注释申明对执行没有任何影响

分析方法:
第一、先优化一下索引,索引对数据查询速度影响很大的。
第二、将日志文件与数据文件分开存放。
第三、优化系统中存储过程的查询条件,这个是提高查询速度的最基本,曾在一个大型公司的数据库中写存储过程,取数是从北京,上海,广州三地取数,数据量超过50万,整个查询不超过 10秒。就是因为索引与存储过程的优化。

–首先从两个方面:
1\分析是硬件的问题,比如内存经常在90%,CPU经常在80%以上,建议加硬件了.提升硬件速度.加内存,内存够的话对整个磁盘的读写能力会减轻很多.我们公司以前的内存是4G,现在升级为64位,可以用16G,速度大幅度提高,但有时也会出现慢,只是有时锁的问题…
  硬盘建议用RAID0+1,现在的硬盘又不贵.数据库一般都建议用RAID10.一是安全,二是速度.都比较有保障.
2\软件方面:
  检测耗用内存,CPU最多的语句或过程,进行跟踪优化,SQL2005中有一个表sys.dm_exec_query_stats可以看到.当然也可以根据Read80Trace程序进行统计跟踪.(比如一个小时的跟踪查看耗用资源最多的语句).
根据这些信息再来优化数据,如:加索引,分区表,….优化语句啊.
总结:以前听过一句话, 数据库慢的80%的因素是SQL语句.所以把SQL语句优化好对速度提高很快的当然加硬件也可以的

A. 按平均 CPU 时间排在前五个的查询
此方案提供有关 CPU 时间、IO 读写以及按平均 CPU 时间排在前五个查询的执行次数的信息。SELECT TOP 5
total_worker_time/execution_count AS [Avg CPU Time],

(SELECT SUBSTRING(text,statement_start_offset/2,(CASE WHEN statement_end_offset = -1 then LEN(CONVERT(nvarchar(max), text)) * 2 ELSE statement_end_offset end -statement_start_offset)/2) FROM sys.dm_exec_sql_text(sql_handle)) AS query_textFROM sys.dm_exec_query_statsORDER BY [Avg CPU Time] DESC
 
还是建议做个SQLDIAG的诊断报告,获得整个系统的性能信息,然后才能更有针对性的做出调整。

1、把系统换成64位,然后加大内存。
2、数据库性能的优化。相信很多查询都是有很大的优化空间的,也不清楚你们有没有专门的数据库维护人员,看一下索引碎片之类的情况。 

No comments: