需求如下:
有一個A表,它的記錄數約在50萬左右,一個B表,它的記錄數在800萬左右,B表需要以每月約50條的記錄數增長。而A表和B表的唯一索引都是key1和key2,這兩個字段大家也可以看作兩表的主鍵。
目前的要求是:
1、需要將B表中與A表中有相同主鍵的記錄的其它字段更新為A表中的字段值。
2、需要將A表中不在B表中的記錄插入B表中。
我的同事根據上面這兩個要求寫出的SQL:
|
出錯現象:
在將以上兩步的SQL語句放入一個存儲過程中去運行后,出現的結果讓人使料不及,連續運行了11個小時竟然沒有出來結果,并且把8個CPU和24G內存的一臺小型機資源耗盡,連telnet都連接不上。后來,在仔細檢查了該存儲過程后,發現第二步中漏掉了一個關聯字段,我們將第二步改成:
|
在執行此SQL語句后,依然許久都沒有出現結果。 通過分析運行該存儲過程時Sybase IQ的日志記錄,發現問題的關鍵出在第2步上。一執行到這里就卡殼。于是,把重點放在對該語句的優化上。看起來用not exists對大表操作時會導致嚴重的性能問題。所以,我們就將第2步分成以下幾個步驟:
|
再次執行改存儲過程后,通過觀察Sybase IQ的運行日志,發現執行完3-5步耗時在100秒左右。整個存儲過程的執行時間不超過2分鐘。
總結:
1、小心“燈下黑”,千萬不要忽略簡單的問題;
2、在日常的數據庫管理中,為了實現同樣的目標,不同的的SQL寫法性能相差可能上萬倍,而這些性能的差異都是可以通過變換思路的方法得以解決;
3、雖然Sybase IQ是目前最快,性能最優良的數據庫引擎,但我們也不應忽視SQL的性能問題;
4、在Sybase IQ中,盡可能用臨時表,并且最好使用update和delete操作,盡可能避免使用not exists操作(對于小表,假如數據在1萬行左右,可以忽略不計), 因為not exists可能會導致對大表操作的性能問題。
新聞熱點
疑難解答