原文地址:http://www.sqlpassion.at/archive/2014/04/08/improving-query-performance-by-using-correct-search-arguments/

今天的文章给大家谈谈在SQL Server上关于indexing的一个特定的性能问题。

问题

看看下面的简单的query语句,可能你已经在你看到过几百次了

-- Results in an Index ScanSELECT * FROM Sales.SalesOrderHeaderWHERE YEAR(OrderDate) = 2005 AND MONTH(OrderDate) = 7GO

这实际上不是SQL Server的限制,而是relational database都是这样的。只要你对一个做了index的列(Search Argument)加了函数操作,数据库引擎就必须再次扫描这个index,而不是去直接执行seek operation

解决方案

为了解决上门的问题,必须要避免在列上门直接应该函数,比如上面的问题可以用下面的代码来代替

-- Results in an Index SeekSELECT * FROM Sales.SalesOrderHeaderWHERE OrderDate >= '20050701' AND OrderDate < '20050801'GO
-- Results in an Index ScanSELECT * FROM Sales.SalesOrderHeaderWHERE CAST(CreditCardID AS CHAR(4)) = '1347'GO
-- Results in an Index SeekSELECT * FROM Sales.SalesOrderHeaderWHERE CreditCardID = CAST('1347' AS INT)GO

通过今天的blog,我想你们已经认识到了不要在做过indexed的列上直接应用函数,不然SQL Server会扫描你整个index,而不是做seek operation。当你的表变得越来越大的时,你会崩溃的。

译后记

这也是我在看微软SQL Server认证考试Exam70-461的TrainingKit的时候,它书里面反复强调的。简单来讲就是保证不要直接用函数作用在做过index的列上,要用函数的话,变通到表达式的右侧来。至于为什么会影响性能。因为我对index还不熟悉,我理解的不是很清晰。

我大概猜想如下,先记下,欢迎讨论。

对某一个列做index,是不是类似对这一列的数据做一个hash映射,当在查找这一列的数据的时候,直接可以做O(1)的操作(是不是就是它讲的seek operation)。如果对这一列使用了函数,SQL Server的机制就是不会重新做一个作用了函数后的列的hash,它就简单的一个一个的比较了。是O(N)的操作了。

更多相关文章

  1. Android屏幕分辨率正确获取及PX,DPI,DP,SP等的对应关系
  2. android 下写文件性能测试
  3. [android]android性能测试命令行篇
  4. Android中对后台任务线程性能的说明及优化
  5. Android特性
  6. Android(安卓)开发性能优化简介
  7. 性能优化之Java(Android)代码优化
  8. 【Android(安卓)Linux内存及性能优化】(八) 系统性能分析工具
  9. 微信小程序性能分析Trace工具

随机推荐

  1. curl获取网页内容出现乱码或为空的解决方
  2. PHP: Join two separate mysql queries i
  3. 从PHP智能模板中剥离空白
  4. 如何在“”之前删除多个UTF-8 BOM序列?
  5. php吧字符串直接转换成数组处理
  6. 为什么我对JSON对象的AJAX调用会返回其特
  7. PHP print_r 转换/还原为数组
  8. 如何在没有任何扩展名的php中保存图像
  9. thinkphp框架里怎么用linux的crontab写ph
  10. MySQL或PHP动态地将行转换为列