继续我的SQL SERVER常见错误系列,来看更多的T-SQL错误。
错在哪里?
如果你看到这样一个查询语句,你能看出问题来吗?
select
o .OrderID
, o .CustomerID
, o .Qty
from Orders o
where datepart ( yyyy , o .OrderDate ) = '2010'
o .OrderID
, o .CustomerID
, o .Qty
from Orders o
where datepart ( yyyy , o .OrderDate ) = '2010'
如果该表有1000条数据,这可能没有问题;但是该表若是有1,000,000条数据,那么这就有问题了。为什么呢?让我们来查看他们的执行计划。
该表有1000行数据,该查询没有使用索引查询OrderDate为2010年的记录,相反该查询使用的是表扫描。原因就是WHERE子句中使用了函数,这意味着索引不能再起作用。
应该用这样的查询代替:
select
o.OrderID
, o.*
, o.Qty
from [OrderItems] o
where o.OrderDate >= '20100101'
这样,可以去掉WHERE子句中的函数,以允许查询优化器应用OrderDate 列上的索引。
在下面查询中,您会发现类似的问题
select
lastname
from Person .Contact
where left(Lastname , 1 ) = 'S'
lastname
from Person .Contact
where left(Lastname , 1 ) = 'S'
这个可以修改为,
select
lastname
from Person .Contact
where Lastname like 'S%'
lastname
from Person .Contact
where Lastname like 'S%'
通常,不应该在列上使用函数而是用另一种方式实现,这样查询就可以使用索引了。
很多时候,我们都这样写查询语句,认为这些函数是高效的。但是,它们会执行表中的每一行;导致对于大量的数据来说,比扫描更高效的查找操作不能使用索引。
当我们写查询语句的时候,要尽量避免在列上应用函数。尽可能从查询中移除函数。下一博客将会讨论计算列的相关内容!