首先,有一句話要認識 : 80%的性能問題由SQL語句引起。
經過看 SYBASE 的書,結合從 MSSQL 遷移過來的系統過程 ,發現以下幾個問題比較重要:
經驗一、where 條件左邊最好不要使用函數,比如 ★★★★★
select ... where datediff(day,date1,getdate())>;0
這樣即使在 date1 列上建立了索引,也可能不會使用索引,而使用表掃描。
這樣的語句要重新規劃設計,保證不使用函數也能夠實現。通過修改,一個系統過程的運行效率提高大約100倍!此外不要使用諸如like '%ab',不能充分利用索引,而要在%前加字符
經驗二、兩個比較字段最好使用相同數據類型,而不是兼容數據類型。比如 int 與 numeric(感覺一般不是太明顯)★★
經驗三、復合索引的非前導列做條件時,基本沒有起到索引的作用。★★★★★
比如 create index idx_tablename_ab on tablename(a,b)
update tablename set c = XX where b>;= XXX and ...
在這個語句中,基本上索引沒有發揮作用。 導致表掃描引起blocking 甚至運行十幾分鐘后報告失敗。
一定要認真檢查 改正措施: 在接口中附加條件
update tablename set c = XX where a = XXX and b>;= XXX
或者建立索引類似于
create index idx_tablename_ba on tablename(b,a)
經驗四、 多個大表的關聯查詢,如果性能不好,并且其中一個大表中取的數據比較少,可以考慮將查詢分兩步執行。★★★★
先將一個大表中的少部分數據 select * into #1 from largetable1 where ...
然后再用 #1 去做關聯,效果可能會好不少。(前提:生成 #1表應該使用比較好的索引,速度比較快)
經驗五、 tempdb 的使用。★★★★★
最好多用 select into ,這樣不記日志 ,尤其是有大量數據的報表時。雖然寫起來麻煩,但值得。
create table #tmp1 (......)這樣寫性能不好。尤其是大量使用時,容易發生tempdb 爭用。
經驗六、 系統級別的參數設置 ★★★★
一定要估計一下,不要使用太多,占用資源 ,太少,發生性能問題。
連接數,索引打開個數、鎖個數 等、 當然 ,內存配置不要有明顯的問題,比如,procedure cache
不夠 (一般缺省20%,如果覺得太多,可以減少一些)。如果做報表經常使用大數據量讀,可以考慮使用
16Kdata cache
經驗七、索引的建立。很重要。★★★★★
clustered index /nonclustered index 的差異,自己要搞清楚。各適用場合,另外如果
clustered index 不允許 重復數,也一定要說明。
索引設計是以為數據訪問快速為原則的,不能 完全(!!) 參照數據邏輯設計的,邏輯設計時的一些東西,
可能對物理訪問不起作用
經驗八、統計數據的更新:大約10天進行 update statistics ,sp_recompile table_name(★★★)
經驗九、強制索引使用 (★★★★)
如果懷疑有表訪問時不是使用索引,而且這些條件字段上建立了合適的索引,可以強制使用
select * from tableA (index idx_name) where ...
這個對一些報表程序可能比較有用。
經驗十、找一個好的監視工具 ★★★
工欲善其事,比先利其器,一點都不錯呀。
我用 DBartisian 5.4 ,監視哪些表被鎖定時間長, blocking 等
還有 sp_object_status 20:00:00 , sp_sysmon 20:00:00 等
以上是我的一點經驗,在不到一個月的時間內,我修改了20個左右的語句和系統過程 ,
系統性能明顯改善,cpu利用 高峰時大約50% 平時 不到30%IO 明顯改善。所有月報表能順利完成 5min 以內。
經驗十一: 綜合以上對IN/EXISTS的討論,我們可以得出一個基本通用的結論:IN適合于外表大而內表小的情況;EXISTS適合于外表小而內表大的情況。
另外,系統中確認不使用的中間數據,可以進行轉移。這些要看系統的情況哦
最后祝你好運氣。
以上為個人經驗,歡迎批評指正!
呵呵 寫完后忘記一個 一定要注意熱點表 ,這是影響并發問題的一個潛在因素。!解決方法: 行鎖模式 如果表的行比較小,可以故意增加一些不用的字段
比如 char(200) 讓一頁中存放的行不要太多。