SQL Server性能优化(6)查询语句建议

1. 如果对数据不是工业级的访问(允许脏读),在select里添加 with(nolock)

SELECT TOP 10 ID
FROM   Measure_heat WITH (nolock)

2. 限制结果集的数据量,如使用TOP 100等来限制返回的行数。实在不行,在数据库内分页。

3. 查询时不要返回不需要的行、列,即不要用SELECT *, 而是用 SELECT 字段名。

4. 注意UNion和UNion all 的区别:UNION ALL好。

5. 避免使用: like  ‘%关键字%’

6. 避免在字段上使用函数:如 upper(“字段”)=值 改成 字段=upper(‘值’) 或者

WHERE DATEDIFF(DAY, 日期,'2005-11-30')>0应改为:WHERE 日期 <'2005-11-30‘。
放在前面会每一行执行一次。

7. 尽量少用”or”关键字,而是用Union语句代替。参考:http://www.cnblogs.com/zping/archive/2008/09/23/1297238.html

8. 用exists来代替in语句。参考:http://www.cnblogs.com/zping/archive/2008/08/05/1260959.html

9. 尽量少用视图,它的效率低。特别的是不要用视图嵌套

10. 没有必要时不要用DISTINCT和ORDER BY,这些动作可以改在客户端执行。它们增加了额外的开销。

11. 如果在 WHERE 子句中使用参数,也会导致全表扫描。

SELECT ID FROM T WHERE NUM=@NUM
可以改为强制查询使用索引:
SELECT ID FROM T WITH(INDEX(索引名)) WHERE NUM=@NUM

12. 慎用游标

13. 不要在子查询中使用count()求和执行存在性检查

--不要使用。当你使用count()时,SQL Server不知道你要做的是存在性检查,它会计算所有匹配的值,要么会执行全表扫描,要么会扫描最小的非聚集索引;
SELECT column_list FROM table WHERE 0 < ( SELECT count ( * ) FROM table2 WHERE ..)
--使用。当你使用EXISTS时,SQL Server知道你要执行存在性检查,当它发现第一个匹配的值时,就会返回TRUE,并停止查询。类似的应用还有使用IN或ANY代替count()。
SELECT column_list FROM table WHERE EXISTS ( SELECT * FROM table2 WHERE ...)

14. 避免使用count(*)获得表的记录数

--这条语句会执行全表扫描才能获得行数。
SELECT COUNT ( * ) FROM dbo.orders
--但下面的SQL语句不会执行全表扫描一样可以获得行数:
SELECT rows FROM sysindexes WHERE id = OBJECT_ID ( ' dbo.Orders ' ) AND indid < 2

15. 避免使用动态SQL,类似如下:动态SQL难以调试和故障诊断,有注入风险,并且查询计划只能在执行时才知道where条件的内容,不利于其使用最优化的执行计划。

Declare @i INT
SELECT name FROM USER WHERE ID = @I

16. 不要在你的存储过程,触发器,函数和批处理中重复调用函数,例如,在许多时候,你需要获得字符串变量的长度,无论如何都不要重复调用LEN函数,只调用一次即可,将结果存储在一个变量中,以后就可以直接使用了

17. 有关触发器,最好不要使用触发器;如果能够使用约束实现的,尽量不要使用触发器;不要在触发器中使用事务型代码。

参考:

a. http://www.cnblogs.com/zping/archive/2012/09/13/2682896.html

b. http://www.cnblogs.com/jyshis/archive/2011/09/16/2178309.html

c. SQL SERVER性能优化综述http://blog.csdn.net/Haiwer/article/details/2826881

d. 十步优化SQL Server中的数据访问:http://my.oschina.net/tangyu/blog/79120

原文地址:https://www.cnblogs.com/ustcyc/p/4512369.html