博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用正确的筛选参数来提高查询性能
阅读量:4564 次
发布时间:2019-06-08

本文共 1441 字,大约阅读时间需要 4 分钟。

在今天的文章里我想谈下SQL Server里与索引相关的特殊性能问题。

问题描述

假设下列的简单查询,在你的日常SQL Server里,这样的查询你已经看到过几百遍了:

1 -- Results in an Index Scan2 SELECT * FROM Sales.SalesOrderHeader3 WHERE YEAR(OrderDate) = 2005 AND MONTH(OrderDate) = 74 GO

用那个简单查询,我们请求在特定年份特定月份里的销售信息。并不复杂。遗憾的是这个查询性能很差——即使在OrderDate列使用了非聚集索引。当你查看执行计划时,你会看到查询优化器选择了在OrderDate列上的非聚集索引,但遗憾的是SQL Server进行的索引的全扫描,而不是高效的查找操作。

 

这真不是SQL Server的局限性,而是关系数据库的工作和思考方式:)只要你在索引列上使用了,数据库引擎必须去扫描那个索引,而不是进行查找操作。

解决方法

在执行计划里为了获得可扩展的查找操作,你必须要换种方式重写你的查询来避免DATEPART函数的调用: 

1 -- Results in an Index Seek2 SELECT * FROM Sales.SalesOrderHeader3 WHERE OrderDate >= '20050701' AND OrderDate < '20050801'4 GO

从重写的查询可以看到,查询返回同样的结果,但我们已经剔除了DATEPART函数的调用。当你查看执行计划时,你会看到SQL Server进行了查找操作——在那个情况下,这个是所谓的局部范围扫描(Partial Range Scan):SQL Server查找到第1个值,然后扫描到请求范围的最有值。如果你想在索引列上下文调用函数,你必须保证在查询里,这些函数调用的执行在你列的右侧。我们来看一个具体的例子。下面查询把CreditCardID索引列转化为CHAR(4)数据类型:

1 -- Results in an Index Scan2 SELECT * FROM Sales.SalesOrderHeader3 WHERE CAST(CreditCardID AS CHAR(4)) = '1347'4 GO

当你仔细看执行计划时,你会看到SQL Server再次扫描整个非聚集索引。如果你的表越来越大,这是真不能扩展的。如果你在查询里在你索引列的右侧执行转化,你就可以在索引列上剔除函数调用,SQL Server就可以进行查找操作:

1 -- Results in an Index Seek2 SELECT * FROM Sales.SalesOrderHeader3 WHERE CreditCardID = CAST('1347' AS INT)4 GO

小结

从这篇文章里,你可以看到,在你的索引列里不直接调用任何函数或间接调用函数是非常重要的。不然的话SQL Server会扫描你的索引,而不是进行高效的查找操作。而且当你表越来越大时,扫描从不扩展。

如果你碰到这个特殊行为的其他好例子,想分享的话,欢迎留言。

感谢关注。

 

转载自:http://www.cnblogs.com/woodytu/p/4646384.html

转载于:https://www.cnblogs.com/icitycloud/p/4653457.html

你可能感兴趣的文章
安卓备份 To Do(待办事项)的数据库
查看>>
vim下正则表达式的非贪婪匹配
查看>>
一个python的计算熵(entropy)的函数
查看>>
spring源码学习——spring整体架构和设计理念
查看>>
模拟window系统的“回收站”
查看>>
OpenCV中的split函数
查看>>
session共享
查看>>
MongoDB divide 使用之mongotempalte divide
查看>>
style不同取值对应的日期、时间格式
查看>>
三星S5_G9008V 解锁联通4G(安卓6.0)
查看>>
android 设置横屏
查看>>
censoring--kmp匹配删减子字符串
查看>>
[git] 更新单个或者指定文件
查看>>
UIImangeView的用法
查看>>
阿里云SDK手册之java SDK
查看>>
js获取select标签选中的值[转]
查看>>
mysql连接出现error node【1045】
查看>>
踩vue的bug
查看>>
Ansible安装及配置
查看>>
浅析Sql Server参数化查询
查看>>