1. 如果对数据不是工业级的访问(允许脏读),在select里添加 with(nolock)
SELECT TOP 10 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