优化查询的几点建议之二

时常,查询在客户端很慢,如果在服务器执行很快。为什么?

这个问题有点复杂,这里我们不考虑网络,死锁等问题,仅就查询而言。

一般来说,查询分为两种,存储过程和动态查询,下面分别讨论:

 

一,存储过程

SQL SERVER 建立查询计划:

存储过程;

自定义函数;

表值函数;

触发器。

 

不建立计划:

VIEW;

INLINE-TABLE FUNCTION.

 

如何建立计划呢?下面几点要注意:

常量,服务器一定要使用;

参数,服务器编译可以嗅到;

局部变量,服务器使用标准假设,取决运算符,推理惟一索引。

 

众所周知,存储过程第一次运行后,服务器会把查询计划放入缓存,下次运行,省略编译。下列事件发生,会清除计划:

ALTER PROCEDURE;

SP_RECOMPILE;

DBCC FREEPROCCACHE;

BUFFER CACHE FULL;

SP_CONFIGURE;

SERVER RESTART.

 

下列事件,会导致部分编译:

表定义变化;

表索引变化;

表统计变化;

SP_RECOMPILE 表变化。

 

下面来看不同计划对应的设置,非常重要!

 

 

 Applications using
ADO .Net, ODBC or OLE DB
SSMS,
Query Analyzer
SQLCMD,
OSQL, BCP,
SQL
Server Agent
ISQL,
DB-Library
ANSI_NULL_DFLT_ONONONONOFF
ANSI_NULLSONONONOFF
ANSI_PADDINGONONONOFF
ANSI_WARNINGSONONONOFF
CONACT_NULLS_YIELD_NULLONONONOFF
QUOTED_IDENTIFIERONONOFFOFF
ARITHABORTOFFONOFFOFF

 

从上图,清楚看出,最重要的是:ARITHABORT,因为客户和服务器设置不同。

 

这个可以解释,为什么客户很慢,服务器快的原因。

可以 SET ARITHABORT OFF 进行测试。

 

二,动态查询

分为两种

非参数的:

SELECT @sql = 'SELECT mycol FROM tbl WHERE keycol = ' + convert(varchar, @value)
EXEC(@sql)

C#

cmd.CommandText = "SELECT mycol FROM tbl WHERE keycol = " + value.ToString();


参数的:

EXEC sp_executesql N'SELECT mycol FROM dbo.tbl WHERE keycol = @value',
                   N'@value int', @value = @value

C#

cmd.CommandText = "SELECT mycol FROM dbo.tbl WHERE keycol = @value";
cmd.Parameters.Add("@value", SqlDbType.Int);
cmd.Parameters["@value"].Value = value;


它编译计划和计划缓存,基本与存储过程一样。有两点不同:

1,服务器寻找存储过程使用名字,动态查询使用查询文本的HASH KEY;

2,默认的SCHAMA 会影响动态查询计划,存储过程不会。

 

三,参数嗅探问题

有时,参数嗅探会产生:

查询使用不适合参数嗅探;

小部分查询不同大量主要查询;

索引结构不合理;

 

几点解决方法,供参考:

  1. Use an index hint to force use of any of the other indexes.
  2. The query hintOPTIMIZE FOR.
  3. Copy @p to a local variable.
  4. OPTION (RECOMPILE) / WITH RECOMPILE
  5. Add the "optimal" index on related columns
  6. Make the index on Column filtered or drop it entirely.

 

 

 



 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值