SqlServer2008查询性能优化

SQL性能杀手

在已经优化了硬件、操作系统和SQL配置的情况下,SQL中的性能杀手:

·低质量的索引

·不精确的统计

·过多的阻塞和死锁

·低质量的查询设计

·低质量的数据库设计

·过多的碎片

·不可重用的执行

·低质量的执行计划

·执行计划频繁重编译

·游标的错误使用

·数据库日志的错误配置

·过多使用或者错误配置tempdb


低质量的索引

对于一个缺乏正确索引的查询,SQL必须在执行查询时读取和处理多得多的数据,这导致磁盘、内存和CPU上有很大的压力,显著的增加查询执行时间。增加查询执行时间导致过多的阻塞和死锁。


不精确的统计

SQL服务器非常依赖基于开销的优化,所以精确的数据分布统计对于有效的索引使用极端重要。没有精准的统计,SQL内建的查询优化器就不能精确的估计查询影响的行数。



性能监测工具

运行perfmon


查询每秒登录的时间

Select cntr_value

From sys.dm_os_performance_counters

Where OBJECT_NAM = ‘’//服务器名称

And counter_name = ‘logins/sec’//每秒登录多少次


识别发生在系统中的等待,查询当前最长的等待

Select top 10 * from sys.dm_os_wait_stats

Order by wait_time_ms desc


当SQL耗尽了缓冲或内存时,SQL中的一个进程(lazy writer)必须不段的工作,这将消费额外的CPU周期并且执行附加的物理磁盘I/O将内存页面写回磁盘


通过下面语句管理最小最大内存配置。

Exec sp_configure ‘min server memory(MB)’

Exec sp_configure ‘max server memory(MB)’

注意:服务器最小内存默认值为0,最大为2147483647,服务器最大内存不能设置为小于4MB。

查询设计分析

·查询设计影响性能的方面

·查询设计有效使用索引的方法

·优化器提示在查询性能上的作用

·数据库约束在查询性能上的作用

·资源密集度较低的查询设计

·有效使用过程缓冲的查询设计

·减少网络开销的查询设计

·减少查询事务开销的技术


一般记住以下建议能确保最佳性能:

·在小的结果集上操作

·有效使用索引

·避免优化器提示

·使用域和参照完整性

·避免资源密集型的查询

·减少网络传输数量

·减少事务开销



在小的结果集上操作

应该限制操作的数据量,包括列数和行数。遵循原则:

·限制选择列表中的列数

·使用高选择性的WHERE子句来限制返回的行数


限制选择列表中的列数

不要使用输出结果不需要的列。例如select *,错误

Select [Name],TerritoryID from SalesTerritory as st

Where st.[Name] = ‘australia’

在NAME列上的覆盖索引使通过索引本身的查询很快,而不需要访问聚集索引。当开启STATISTICS IO和STATISTICS TIME开关,将得到以下逻辑读取数量和执行时间

Table ‘SalesTerritory’.Scan count 0, logical reads 2,CPU time = 0ms,elapsed time = 17ms


使用高选择性的WHERE子句

在WHERE子句中引用的列的选择性控制着列上索引的使用。



11.3有效的使用索引

索引使用的查询设计原则:

·避免不可参数化的搜索

·避免在WHERE子句列上使用算数运算符

·避免WHERE子句列上的函数


11.3.1避免不可参数化的搜索



11.3.2避免WHERE子句列上的算术运算符

如:

SELECT * FROM TABLE AS POH

WHERE POH.ID * 2 = 3400

改为

SELECT * FROM TABLE AS POH

WHERE POH.ID = 3400/2


11.3.3避免WHERE子句列上的函数

如:

SELECT D.NAME FROM TABLE AS D WHERE SUBSTRING(D.[NAME],1,1) = ‘F’

改为:

SELECT D.NAME FROM TABLE AS D WHERE D.[NAME] LIKE ‘F%’


11.4避免优化器提示


11.5使用域和参照完整性

11.5.1非空约束

非空约束用于定义特定列中不能输入NULL值从而实现域完整性。

对比没有NULL和有NULL的执行过程


没有NULL的


有NULL的,仅仅只是在后面增加了,or p.firstname is null

注意:当数据为知时,也许不能设定默认值。这时候又将出现NULL。这是不可避免的,但是要尽可能的减少这样的情况。

当不可避免的要处理NULL值时,可以使用过滤索引来从索引中删除NULL的值,从而改进索引的性能。


11.5.2声明参照完整性

声明参照完整性用于定义父表和子表上的参照完整性。它确保子表中的记录只当父表中存在对应记录时存在。这个原则唯一例外的是,链接子表和附表行的子表标识符可以为NULL值。


11.6避免资源密集型查询

减少查询覆盖的技术有:

·避免数据类型转换

·使用EXISTS代替COUNT(*)来验证数据存在

·使用UNION ALL代替UNION

·为聚合和排序操作使用索引

·避免批查询中的局部变量

·小心命名存储过程

(2013-3-25)

你可能感兴趣的:(SqlServer2008查询性能优化)