经验一、where 条件左边最好不要使用函数,比如:
select … where datediff(day,date_column,getdate())>0
这样即使在date_column列上建立了索引,也可能不会使用索引,而使用全表扫描。
这样的语句要重新规划设计,保证不使用函数也能够实现。通过修改,一个系统过程的运行效率提高大约几十倍甚至上百倍!此外不要使用诸如like ‘%ab’,不能充分利用索引,而要在%前加字符。
经验二、两个比较字段最好使用相同数据类型,而不是兼容数据类型。比如 int 与 numeric(感觉一般不是太明显)。
经验三、复合索引的非前导列做条件时,基本没有起到索引的作用。
比如 create index idx_tablename_ab on tablename(a,b)
update tablename set c = XX where b>= XXX and …
在这个语句中,只用了索引列b而没用索引列a做查询条件,基本上索引没有发挥作用。 导致表扫描引起blocking 甚至运行十几分钟后报告失败。
一定要认真检查 改正措施: 在接口中附加条件
update tablename set c = XX where a = XXX and b>= XXX
或者建立索引类似于
create index idx_tablename_ba on tablename(b,a)
经验四、 多个大表的关联查询,如果性能不好,并且其中一个大表中取的数据比较少,可以考虑将查询分两步执行。
先将一个大表中的少部分数据 select * into #tmp from large_table where …
然后再用 #tmp 去做关联,效果可能会好不少。(前提:生成 #tmp表时,访问large_table 用到了比较好的索引,速度比较快)
经验五、 tempdb 的使用。
最好多用 select into ,这样不记日志 ,尤其是有大量数据的报表时。虽然写起来麻烦,但值得。
create table #tmp (……)这样写性能不好。尤其是大量使用时,容易发生tempdb 争用。
经验六、 系统级别的参数设置
一定要估计一下,不要配置太多,占用资源 ,配置太少,发生性能问题。
连接数,索引打开个数、锁个数 等、 当然 ,内存配置不要有明显的问题,比如,procedure cache
不够 (一般缺省20%,如果觉得太多,可以减少一些)。如果做报表经常使用大数据量读,可以考虑使用 16K data cache