更新: 2011-07-28字體: 【大中小】點擊: 18
 
最近項目原因,有機會更多地使用到了Sybase ASE 、IQ 工具,下面總結幾點使用的經驗。 1、sybase ASE ,sybase IQ 都支持bcp out ; 但是IQ不支持bcp in,Sybase IQ導入數據時候必須把數據源放到本地load進去 ,而 ASE支持異地數據的 bcp in。 2、IQ建SERVERNAME(即是在dsedit 的 Server name)時候必須與IQ的數據庫名字是一樣的。否則會報數據庫找不到(即 bcp時會找不到該IQ數據庫)。 以下是我同事老余總結的使用經驗: 他的博客地址是:http://blog.csai.cn/user1/16350/index.Html 以下,是我在項目中針對Sybase IQ的SQL寫法總結出來的一些想法和心得,希望能給遇到類似問題的朋友們一些啟發。 1、在Sybase IQ中盡可能使用臨時表 2、使用Insert 代替 Update操作 3、在需要兩個大表(分別在100萬記錄集以上)關聯往第三張表插入時,建議先做Intsert,再做Update. 4、在需要根據第二張表的內容決定是否將第一張表的數據插入到第三張表時。如果前面兩張表的記錄數在100萬以上建議不要去用Exists,否則會極大的影響性能。有可能半天都跑不出數據來。 此時,建議先做Intsert操作,再做delete操作。 這兩種做法的效率可能相差在100倍以上。 5、根據需要選擇建立適當的索引,如LF,HG,HNG,CMP索引等以下是在一個項目中使用SQL不適當導致Sybase IQ嚴重性能問題的真實的案例。 在項目中,有一個A表記錄數在50萬左右,一個B表記錄數在800萬左右,並且B表以每月約50條的記錄數增長。A表和B表的唯一索引都是key1和key2,這兩個字段也可以視為兩表的主鍵。現在要求1、將B表中與A表中有相同主鍵的記錄的其它字段更新為A表中的字段值。2、將A表中不在B表中的記錄插入B表中。 我們的項目組成員在實現這兩個要求時的SQL如下: #1: update B set a.col1=b.col1, a.col2=b.col2, ....... from A where A.key1=B.key1 and A.key2=B.key2 #2 insert B select key1,key2,col1,col2..... from A where not exist(select 1 from B where key1=A.key1) 將以上兩步的SQL語句放入一個存儲過程中去運行,結果連續運行了11個小時沒有出來結果,並且把8個CPU和24G內存的一台小型機資源耗盡,連telnet都連接不上。後來,我仔細檢查了該存儲過程,發現第二步中漏掉了一個關聯字段,把第二步改成: #2 insert B select key1,key2,col1,col2..... from A where not exist(select 1 from B where key1=A.key1 and key2=A.key2) 執行該SQL語句,仍然半天出不來結果。 通過分析運行該存儲過程時Sybase IQ的日志記錄,發現問題的關鍵出在第2步上。一執行到這裡就卡殼。於是,把重點放在對該語句的優化上。看起來用not exists對大表操作時會導致嚴重的性能問題。所以,我就換了個思路,把第2步分成以下步驟: #3 select * into #tmp from A # 4 delete #tmp from B where #tmp.key1=A.key1 and #tmp.key2=A.key2 #5 insert into B select * from #tmp 再次執行改存儲過程,通過觀察Sybase IQ的運行日志,發現執行完3-5步耗時在100秒左右。整個存儲過程的執行時間不超過2分鐘。 通過對這次IQ的優化,我總結出以下幾點: 1、簡單的問題其實並不簡單,也許人最容易在簡單的地方載跟頭,越是簡單的東西有時候越值得仔細思考; 2、在數據庫管理中為了實現同樣的目標,不同的的SQL寫法性能相差可能上萬倍,而這些性能的差異都是可以通過變換思路的方法得以解決; 3、即使在Sybase IQ這個目前被視為最快,性能最優良的數據庫引擎中也十分有必要關注SQL的性能問題; 4、在Sybase IQ中盡可能使用臨時表,盡可能使用update和delete操作,盡可能避免使用not exists操作(當然對於小表,如數據在1萬行左右的,可以不必十分關注), not exists可能導致對大表操作的性能問題。