公司有個項目,是使用kettle從oracle上統計,再將結果跟oracle中目標表進行對比更新。接手後,走了一些彎路,中間各類嘗試都不盡如人意,也學了kettle的一些組件的用法。正好趁着機會記錄 一下。mysql
1、背景:sql
需求其實很簡單,在源oracle中,有大批量的表,是使用定時調度從其餘不一樣的數據庫(oracle,mysql,sybase,dameng,sqlserver)中將 「表信息」,「字段信息」,「註釋信息」等元數據表,拉取過來,分別作好編號存儲。數據庫
而kettle要實現的功能:oracle
① 則是從這些源數據表中,將表名、字段名、字段註釋、字段長度、字段類型等信息關聯出來。sqlserver
② 並與以前已經作好的一張結果表作關聯更新。優化
③ 將「元數據有變動」的表的四元素(type,length,primary,comment)信息進行update。spa
④ 若是該字段已經沒有了被刪除了,則有專用字段標記爲"1"。server
⑤ 若是是新來的字段,則insert插入目標表。blog
2、歷程:索引
1. 一開始,機敏的同事使用了一個SQL腳本,用了oracle中的 merge using() matched ....用法,——若是查詢結果與目標結果的 table_name和 column_name關聯上,則直接將四元素update到目標表中;若沒關聯上,則直接insert到目標表中。
2. 問題初現: 初步的邏輯至關於:只要關聯上,就必須update,這樣來講,沒有任何變化的字段,也要update一次,形成大量的update實際上是能夠避免的。並且已刪除字段的標記也未實現。
3. 趟雷:
① 最開始,使用kettle的組件來實現SQL中的邏輯,就不貼圖了,太長了,並且運行起來的效率低的可怕,後被pass。
② 後來嘗試,將SQL優化:
創建臨時表;
join的數據的列裁剪;
都用了一遍,可是毫無卵用....效率仍然低(在真實生產環境上直接都跑不動了)
③ 後來嘗試了一個新的用法: kettle中有個組件叫「合併記錄」: 。 這個小老弟看着不起眼,其實很厲害——它能夠將兩組數據流進行比對,一個原始的,一個「新來的」,用新來的流與原始的流作比對,並在新產生的流中作標記,標記出哪些是沒變的,哪些是新加的(new),哪些是刪除了的(deleted),哪些是改變了的(changed)。
當時一看,這不就是爲這需求量身打造的組件,直接用起來!
改造邏輯:
查詢的SQL保留,可是再從目標表查詢出全量數據,將這兩個流作比對,用「合併記錄」的組件將各類狀況的記錄都標記出來,在後續的流程中可使用組件來篩選和進行後續的操做。
改造完成後的圖以下:
這樣,就將「須要更新」的,「須要插入的」,須要「標記爲刪除的」分別篩選出來,單獨進行更細或者插入的操做了。
然而,仍是出現了新的問題,在「更新」和」同步「 以後,速度仍然慢。
保存出問題了,中間寫的沒有了,如今精簡的補充一下:
解決方案:
創建索引——> 目標表(table_name,column_name)。
update的速度——>大幅度提高。
3、總結:
① 對於不通的方式,最多2天,不要再深刻研究,問題必定不是在整個方向上。
② 解決問題要有邏輯性,哪怕在紙上寫出來,將問題一個個的羅列,解決,梳理,能對問題有個明確的方向。
③ 多上cnblog看看大神的數據庫筆記。。。