SQL Server 查询性能优化——索引与SARG(三)

上接SQL Server 查询性能优化——索引与SARG(二)

 

2  请不要进行负向查询

除了不应该对字段数据进行计算外,非SARG 语句的格式语句还包含在WHERE条件子句中,使用负向查询操作符。 

如NOT 、!=、<> 、!>、!<、NOT EXISTS 、NOT IN及NOT LIKE 等,因为通过有顺序的索引结构,SQL SERVER 可以有效地利用二分法进行查找,快速找到相应的数据,但是如果查询条件是不要什么数据,其余的都要(就是负向查询), 则 无法利用索引进行二分查找,只能进行全表扫描或聚集索引扫描。

以下同样是负向操作健立的SARG 条件查询与非SARG 条件查询范例。从中可以看出两者的执行成本是不一样的,相差十倍左右,但是其数据查询的记录数量也不一样。个人理解查询优化程序是根据数据查询的记录数量,来决定使用哪种执行计划。

       

逻辑读

 执行成本

SELECT *

  FROM

 [WBK_PDE_

LIST_ORG_

HISTROY] 

where 

QTY_1=312

 

有主键(索引1,索引2)

1

'WBK_PDE_LIST_ORG_HISTROY'。扫描计数1,逻辑读取137 次,物理读取次,预读次,lob 逻辑读取次,lob 物理读取次,lob 预读次。

137

 
 

 

0.121935

无主键(索引2)

2

'WBK_PDE_LIST_ORG_HISTROY'。扫描计数1,逻辑读取43 次,物理读取次,预读次,lob 逻辑读取次,lob 物理读取次,lob 预读次。

 

43

 
 

 

0.121935

SELECT *

  FROM 

[WBK_PDE_

LIST_ORG_

HISTROY]

 where

 QTY_1<>312

 

有主键(索引1,索引2)

3

'WBK_PDE_LIST_ORG_HISTROY'。扫描计数1,逻辑读取1314 次,物理读取次,预读次,lob 逻辑读取次,lob 物理读取次,lob 预读次。

 

1314

 
 

 

1.03687

无主键(索引2)

4

'WBK_PDE_LIST_ORG_HISTROY'。扫描计数1,逻辑读取1306 次,物理读取次,预读次,lob 逻辑读取次,lob 物理读取次,lob 预读次。

 

1306

 
 

 

1.03687

           

 

 小结:

查询语句

逻辑读

查询记录数量

执行成本

1

137

37

0.121935

2

43

37

0.121935

3

1314

60796

1.03687

 4  1306  60796  1.03687
       

 

3 不要在WHERE子句中对字段使用函数

在查询语句中对字段使用函数,就是对字段数据进行计算,所以这些都不算是SARG。使用函数之后 ,SQL SERVER 需要将数据表内所有记录的相关字段输入到函数中,如果有100万条记录,就需要调用函数100万次,这将是性能杀手。

下面列出两个非SARG与SARG的查询成本区别的示例。

     

逻辑读

 
   

SELECT *

   FROM [WBK_PDE_LIST_ORG_HISTROY] where dbo.f_qty(QTY_1,G_QTY)=400

   

数值函数计算

1

'WBK_PDE_LIST_ORG_HISTROY'。扫描计数1,逻辑读取1428 次,物理读取次,预读次,lob 逻辑读取次,lob 物理读取次,lob 预读次。

 

1428

 
 

 

1.03687

 

SELECT *   FROM [WBK_PDE_LIST_ORG_HISTROY] where QTY_1=200 and G_QTY=200

   

2

'WBK_PDE_LIST_ORG_HISTROY'。扫描计数1,逻辑读取428 次,物理读取次,预读次,lob 逻辑读取次,lob 物理读取次,lob 预读次。

 

428

 
 

 

0.42645

   

 SELECT * FROM [WBK_PDE_LIST_ORG_HISTROY] where dbo.[f_ByteLeft](wbook_no,14)='BE404942450013'

   

字符函数计算

3

'Worktable'。扫描计数0,逻辑读取次,物理读取次,预读次,lob 逻辑读取次,lob 物理读取次,lob 预读次。

'WBK_PDE_LIST_ORG_HISTROY'。扫描计数2,逻辑读取850 次,物理读取次,预读次,lob 逻辑读取次,lob 物理读取次,lob 预读次。

850

 
 

 

1.03904

 

SELECT *  FROM [WBK_PDE_LIST_ORG_HISTROY] where wbook_no='BE404942450013'

   

4

'WBK_PDE_LIST_ORG_HISTROY'。扫描计数1,逻辑读取次,物理读取次,预读次,lob 逻辑读取次,lob 物理读取次,lob 预读次。

 

3

 
 

 

0.0033071

         

 

小结:

查询语句

逻辑读

查询记录数量

执行成本

1

1428

3873

1.03687

2

136

37

0.42645

3

850

3873

1.03904

 4 3 22  0.0033071
       
posted @   DotNet菜园  阅读(4376)  评论(1编辑  收藏  举报
编辑推荐:
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· NetPad:一个.NET开源、跨平台的C#编辑器
点击右上角即可分享
微信分享提示