SQLServer海量数据查询代码优化以及建议(二)

2015-07-21 16:26:06 · 作者: · 浏览: 1
后务必将所有的临时表显式删除,先 truncate
table ,然后 drop table ,这样可以避免系统表的较长时间锁定。


17.在所有的存储过程和触发器的开始处设置 SET NOCOUNT ON ,在结束时设置 SET
NOCOUNT OFF 。无需在执行存储过程和触发器的每个语句后向客户端发送 DONE_IN_PROC
消息。


18.尽量避免大事务操作,提高系统并发能力。

19.尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。

20. 避免使用不兼容的数据类型。例如float 和int、char 和varchar 、binary 和varbinary 是不
兼容的。数据类型的不兼容可能使优化器无法执行一些本来可以进行的优化操作。例如:
SELECT name FROM employee WHERE salary > 60000
在这条语句中,如salary 字段是money 型的,则优化器很难对其进行优化, 因为60000 是个整型
数。我们应当在 编程时将整型转化成为钱币型,而不要等到运行时转化。


21.充分利用连接条件,在某种情况下,两个表之间可能不只一个的连接条件,这时在 WHERE
子句中将连接条件完整的写上,有可能大大提高查询速度。
例:
SELECT SUM(A.AMOUNT) FROM ACCOUNT A,CARD B WHERE A.CARD_NO = B.CARD_NO
SELECT SUM(A.AMOUNT) FROM ACCOUNT A,CARD B WHERE A.CARD_NO = B.CARD_NO AND
A.ACCOUNT_NO=B.ACCOUNT_NO
第二句将比第一句执行快得多。


22、使用视图加速查询
把表的一个子集进行排序并创建视图,有时能加速查询。它有助于避免多重排序 操作,而
且在其他方面还能简化优化器的工作。例如:
SELECT cust.name,rcvbles.balance,??other columns
FROM cust,rcvbles
WHERE cust.customer_id = rcvlbes.customer_id
AND rcvblls.balance>0
AND cust.postcode>“98000”
ORDER BY cust.name
如果这个查询要被执行多次而不止一次,可以把所有未付款的客户找出来放在一个视图中,
并按客户的名字进行排序:
CREATE VIEW DBO.V_CUST_RCVLBES
AS
SELECT cust.name,rcvbles.balance,??other columns
FROM cust,rcvbles
WHERE cust.customer_id = rcvlbes.customer_id
AND rcvblls.balance>0
ORDER BY cust.name

然后以下面的方式在视图中查询:
SELECT * FROM V_CUST_RCVLBES
WHERE postcode>“98000”
视图中的行要比主表中的行少,而且物理顺序就是所要求的顺序,减少了磁盘I/O,所以查
询工作量可以得到大幅减少。


23、能用DISTINCT 的就不用GROUP BY
SELECT OrderID FROM Details WHERE UnitPrice > 10 GROUP BY OrderID
可改为:
SELECT DISTINCT OrderID FROM Details WHERE UnitPrice > 10

24.能用UNION ALL 就不要用UNION
UNION ALL 不执行SELECT DISTINCT 函数,这样就会减少很多不必要的资源


25.尽量不要用SELECT INTO 语句。

SELECT INOT 语句会导致表锁定,阻止其他用户访问该表。
上面我们提到的是一些基本的提高查询速度的注意事项,但是在更多的情况下,往往需要反复
试验比较不同的语句以得到最佳方案。最好的方法当然是测试,看实现 相同功能的SQL 语
句哪个执行时间最少,但是 数据库中如果数据量很少,是比较不出来的,这时可以用查看执
行计划,即:把实现相同功能的多条SQL 语句考到 查询分析器,按CTRL+L 看查所利用的索
引,表扫描次数(这两个对性能影响最大),总体上看询成本百分比即可。