1. 多列索引使用原则
则应考虑列的顺序。用于等于(=)、大于(>)、小于(<)或between搜索条件的where 字句或者参与联接的列应该放在最前面。其它列应该基于其非重要级别进行排序,就是说,从最不重复的列到最重复的列。对于内容基本重复的列,比如只有1和0,禁止建立索引,因为该索引选择性极差,在特 定的情况下会误导优化器做出错误的选择,导致查询速度极大下降。当一个索引有多个列构成时,应注意将选择性强的列放在前面。
2、合理使用EXISTS, NOT EXISTS字句
如下所示:
SELECT SUM(T1.C1) FROM T1 WHERE ((SELECT COUNT(*) FROM T2 WHERE T2.C2=T1.C2)>0)
SELECT SUM(T1.C1) FROM T1 WHERE EXISTS(SELECT * FROM T2 WHERE T2.C2=T1.C2)
两种产生相同的结果,但是后者的效率显然要高过于前者。银行后者不会产生大量锁定的表扫描或是索引扫描。
经常需要些一个T_SQLL语句比较一个父结果集和子结果集,从而找到是否存在在父结果集中有而在子结果集中乜嘢的记录,如:
SELECT _a.hdr_key FROM hdr_tb1 a -----------tb1 a 表示tb1用别名a代替
WHERE NOT EXISTS (SELECT * FROM dt1_tb1 b WHERE a.hdr_key = b.hdr_key)
SELECT _a.hdr_key FROM hdr_tb1 a -----------tb1 a 表示tb1用别名a代替
LEFT JION dt1_tb1 b ON a.hdr_key = b.hdr_key WHERE b.hdr_key IS NULL
SELECT hdr_key FROM hdr_tb1
WHERE hdr_key NOT IN (SELECT hdr_key FROM dt1_tb1)
三种写法都可以得到同样的结果集,但是效率是依次降低
3. WHERE 字句中关系运算符的选择
b)、WHERE字句中尽量不要使用NOT运算符,如:NOT IN ,NOT EXISTS, NOT>、NOT<等等NOT运算符一般可以去除。如NOT SALARY >10000K可以改为:salary<=100,如避免使用NOT IN,可以使用 left outer jion代替它。
c)、where 字句中条件表达式间逻辑关系为AND时,将条件为假的概率高的放在前面,概率相同、条件计算简单的放在前面。
d)、尽可能不要用Order by字句。使用Order by时,尽量减少列数、尽量减少排序数据行数、排序字段尽量是数字型(尽量不要是字符型)。GROUP BY、 SELECT DITINCT、UNION等字句,也经常导致Order运算。
e)、不要使用Select count(*)方式来判断记录是否存在,建议使用Select top 1 from table1 where ……。
f)、不要使用Group by而没有聚合列。
g)、避免Select 语句的Where 字句条件用于假。如:where 1=0;
h)、如果有多表连接时,应该有主从表之分,并尽量从一个表读取数,如select a.col1,a.col2 from a jion b on a.col3=b.col4 where b.col5=’a’.
i)、在where 字句中,如果有多个过滤条件,应将所有列或过滤记录数量最多的条件应该放在前面。
4. 使用Truncate清空表
5. Union和Union all
Union将两个结果集合并后,会消除重复记录,而Union all不会消除重复记录,而是直接将两个结果集直接合并。明确得知两个结果集中没有重复记录或者重复记录不影响使用,建议使用Union all 代替Union。因为Union在消除重复记录的过程中需要进行排序过滤操作,对大结果集这种排序操作会非常影响性能。
6. Code、Name字段长度
如果业务表中的Code、Name需要建立唯一索引,那Code长度小于nvarchar(32),Name长度小于nvarchar(200)比较合 适,不要超过255,避免超过索引键长度900bytes的限制