SPL可將文本文件按體積大體分爲N段,只讀取其中一段。好比cardInfo.txt存儲着一千萬條人口信息,將其分爲十份,取第二份,代碼能夠寫做:算法
按體積大體分段,而不是按行數精確分段,目的是提升分段性能。好比在IDE中觀察A2或A3的前幾個字段,能夠看到行數並不是精確的100萬(與具體數據有關):數據庫
分段讀取可應用於多線程計算,從而提升讀取性能。好比用2個線程分別讀取cardInfo.txt,各線程計算本段行數,最後合併爲總行數,可用以下代碼:多線程
語句fork語句適合算法較複雜的狀況,當算法比較簡單時,可用cursor@m直接分段讀取。好比前面的代碼能夠改寫以下:函數
上述代碼指定了線程數,若是省略線程數,則用配置文件中的「parallet limit」當作默認線程數。假設parallet limit=2,則上述代碼能夠改寫成:性能
爲了驗證分段讀取先後的性能差別,下面設計一個算法,分別用單線程和2線程計算cardInfo.txt的總行數,能夠看到性能顯著提高:spa
經過JDBC取數時,有時會遇到數據庫負載雖然不重,但取數性能仍然較差的狀況,這種狀況下能夠用並行取數提升性能。線程
好比Oracle數據庫有一張通話記錄表callrecord,記錄數100萬條,索引字段是callTime,且數據基本按該字段平均分佈。採用非並行取數時,能夠發現性能不夠理想,代碼以下:設計
改成2線程並行取數後,能夠看到性能提高明顯,代碼以下:索引
既然要並行取數,就要把源數據分紅多個區間,使每區間的數據量大體相等。在這個例子中,索引字段是時間類型callTime,因此先用A7求出callTime的數據範圍,再用A8將該範圍平均分紅2個時間區間。以後在A9進行並行計算,每一個線程以各自的時間區間爲參數執行SQL,取數結果將大體相等。最後合併多線程的取數結果,做爲最終結果。隊列
函數range很是適合對數據分段。該函數可將某範圍平均分爲N個區間,得到第i個區間,且可根據範圍的數據類型自動調整區間的數據類型。本例的範圍類型是datetime,則函數range將範圍按秒均分,返回類型也是datetime。若是範圍類型是date,則函數range按天均分;若是範圍類型是整數,則函數range按整數均分。
上面例子中,分段字段是索引,若是沒有創建索引,則查詢性能會出現降低。在這種狀況下,並行取數仍然能夠帶來明顯的性能提高,因此能夠用相同的方法。
上面例子中,源數據基本按callTime平均分佈,所以容易使各區間的數據量大體相等,若是源數據分佈很不平均,能夠考慮按行號分段。每種數據庫都有生成行號的方法,好比oralce可用rownum。
除了單表單SQL並行取數,SPL也支持多表多SQL並行取數。好比某報表格式較複雜,須要SPL執行多個SQL,並按必定的格式拼出結果集。當採用非並行取數時,能夠發現性能不夠理想,代碼以下:
改成4線程並行取數後,能夠看到性能提高明顯,代碼以下:
須要注意的是,並行取數時任務數可大於並行數。好比上面代碼共8個任務,但同時執行的任務只有4個,其餘待執行的任務排在隊列中,若是某個小任務先執行完成,SPL會從隊列中取下一個任務並執行它。能夠看到,當任務數較多時,即便各任務負載相差較大,也能充分發揮硬件性能。
當數據量太大時,除了分庫計算,還能夠進行混合數據源並行計算,後者性能更高。具體作法是:把數據分爲兩部分(或多部分),一部分存儲在數據庫中,一般是當前實時數據,一部分存儲在組文件,一般是歷史數據,再對兩種數據源進行並行計算,從而得到更高性能。
好比歷史訂單存儲在orders.ctx中,當前訂單存儲在數據庫orcl中,請按年、月分組,對各組數據的amount字段求和。SPL代碼以下:
注意fork……fork……的用法。若是fork語句塊下接非fork語句塊,則二者順序執行,若是fork語句塊下接fork語句塊,則二者並行執行。