一般在写SQL的时候应该避免在条件中使用函数,因为这样就不能有效的使用索引,从而无法生成高效的执行计划。
SQL Server提供了计算列可以帮助我们解决这个问题。 我们举个普通的例子。有很多公司使用SQL Server Collcation为大小写敏感的,因为没有办法控制用户的输入(当然在程序中进行转化也是可以的,比如全部转为大写,但是当时设计的时候很多程序员都没有考虑到),所以再做查询的时候就必须要强制转化。
下面的语句就无法使用到索引: select * from t wherelower(c1) = 'az'.
但是我们可以通过增加计算列解决这个问题:
setstatistics profile on go --note that this query does table scan because of the lower function applied select * from t where lower(c1) = '00' go set statistics profile off go --let's add a computed column and create index on this computed column alter table t add c2 as lower(c1) PERSISTED o create index indx_c2 on t(c2) go set statistics profile on go --note that this query does index seek select * from t where lower(c1) = '00' go set statistics profile off
通过增加索引列以后我们看一下结果,没有计算列索引之前我们只能用Table Scan,增加计算列索引之后我们就可以用Seek了。
注意:如果不使用PERSISTED 关键字,计算列是未实际存储在表中的虚拟列。每当在查询中引用计算列时,都将重新计算它们的值。使用PERSISTED 关键字计算列实际存储在表中。如果在计算列的计算更改时涉及任何列,将更新计算列的值。
另外计算列的表达式可以是非计算列的列名、常量、函数,也可以是用一个或多个运算符连接的上述元素的任意组合。
由于存储计算列需要额外的空间并且函数复杂的话需要CPU资源,所以大家在使用的时候需要先做测试。
更多计算列信息请参考MSDN:http://msdn.microsoft.com/zh-cn/library/ms191250(v=sql.105).aspx