效能最佳化技巧:前半有序時的排序
一、 問題背景與適用場景
在對資料集進行排序運算時,有時會遇到這樣一種場景:資料集T已經按欄位a有序,而欄位b無序,現在我們要將T按a、b排序,我們稱之為前半有序(a有序)的排序。此時我們能想到一種最佳化的排序方法:從T中先取出a值相同的一組記錄,再這一組內對b排序。然後再依次取出下一組a值相同的記錄,重複這個動作,直到完成T中所有記錄的排序。這種方法的好處是不需要對T中所有記錄進行大排序,一次只需取出一小組,對記憶體容量要求大大減低,只需能裝下每個小組即可。
遺憾的是SQL並不支援這種最佳化演算法,只能所有記錄進行大排序,而SPL提供了對這種演算法的支援,下面我們例項測試一下,並與Oracle作對比。
二、 測試環境與任務
測試機有兩個Intel2670 CPU,主頻2.6G,共16核,記憶體64G,SSD固態硬碟。在此機上安裝虛擬機器來測試,設定虛擬機器為16核、8G記憶體。
在虛擬機器上建立資料表salesman1,共兩個欄位:area(字串)、salesman(字串),生成資料記錄4億行,按area升序排列,area不同值共2000個,每個area對應salesman為20萬個。將此表資料匯入Oracle資料庫,同時用它生成集算器SPL組表來進行測試。
再建另一張表salesman2作大資料量測試,資料表結構不變,總資料記錄20億行,area值4000個,每個area對應50萬個salesman。
測試任務都是要對錶按照area、salesman排序。
三、 小資料量測試
1. Oracle測試
編寫測試SQL如下:
select area, salesman from salesman1 order by area, salesman
本來只需這一句簡單的SQL即可,不過這個排序結果的輸出時間卻非常長,為了減少輸出量,只統計排序過程的用時,我們不輸出排序後的全部結果,而只輸出中間位置的一行,也就是行號為2億的那一行,所以SQL語句改寫如下:
select area, salesman from (
select area, salesman, rownum rn from (
select area, salesman from salesman1 order by area, salesman
)
) where rn=200000000;
要多說一句,這個查詢其實沒有什麼業務意義,純粹是為了迫使資料庫大排序且避免統計輸出時間的 。
2. SPL測試
編寫SPL指令碼如下:
|
A |
1 | =now() |
2 | =file("/home/ctx/salesman1.ctx").create().cursor(area,salesman) |
3 | =A2.group@qs(area;salesman) |
4 | =A3.skip(199999999) |
5 | =A3.fetch(1) |
6 | =interval@s(A1,now()) |
group@qs中選項s表示對資料集只排序,不分組;選項q表示資料集對分號前的分組表示式(area)是有序的,請求使用前半有序時的排序方法按分號後的 表示式(salesman)排序。
四、 大資料量測試
1. Oracle測試
編寫測試SQL如下:
select area, salesman from (
select area, salesman, rownum rn from (
select area, salesman from salesman2 order by area, salesman
)
) where rn=1000000000;
輸出行號為10億的一行。
2. SPL測試
編寫SPL指令碼如下:
|
A |
1 | =now() |
2 | =file("/home/ctx/salesman2.ctx").create().cursor(area,salesman) |
3 | =A2.group@qs(area;salesman) |
4 | =A3.skip(999999999) |
5 | =A3.fetch(1) |
6 | =interval@s(A1,now()) |
五、 測試結果
測試結果如下,單位(秒):
資料量 | 4億行 | 20億行 |
|
Oracle | 326 | 2556 | |
SPL | 186 | 1266 |
從測試結果看,SPL前半有序排序與Oracle的大排序相比,資料量4億行時,執行時間只有60%,20億行時只有50%,可見效能提升很多,資料量越大時效果越顯著。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69990085/viewspace-2755281/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 前半有序的大資料排序大資料排序
- Laravel 5 框架效能最佳化技巧Laravel框架
- 【文章筆記】效能最佳化技巧參考筆記
- 時間戳效能最佳化時間戳
- Java常見排序演算法之插入排序-簡單的效能優化技巧Java排序演算法優化
- Linux啟動時間最佳化技巧Linux
- 解析MySQL資料庫效能最佳化的六大技巧MySql資料庫
- Linux伺服器效能最佳化有哪些常用技巧?Linux伺服器
- 程式設計技巧整理:Java程式效能最佳化總結!程式設計Java
- 1117陣列排序的技巧陣列排序
- 好程式設計師Java培訓分享-簡單的效能最佳化技巧程式設計師Java
- 活字格效能最佳化技巧(1)——如何利用資料庫主鍵提升訪問效能資料庫
- 大自然夜晚睡眠前半段會衰弱時她的新觸覺
- Windows最佳化技巧Windows
- python最佳化技巧Python
- sql最佳化技巧SQL
- 最佳化SQL Server索引的技巧SQLServer索引
- 4個最佳化MongoDB的技巧MongoDB
- KaiwuDB 多模資料庫-時序效能最佳化AI資料庫
- 如何最佳化程式的效能
- 常用的效能最佳化方法
- 報表的效能最佳化
- Python 程式設計高效技巧:最佳化、異常處理與效能提升Python程式設計
- 堆排序和快速排序效能比較排序
- 從KDD 2018最佳論文看Airbnb實時搜尋排序中的Embedding技巧AI排序
- group by排序,derived_merge最佳化的坑排序
- Oracle常用的16個最佳化技巧Oracle
- Python小技巧:一種字串的排序方式Python字串排序
- PostgreSQL IO最佳化技巧SQL
- 最佳化iOS小技巧iOS
- Unity效能最佳化CPU最佳化Unity
- 基於Python的效能最佳化Python
- Redis效能最佳化的18招Redis
- JavaScript效能最佳化JavaScript
- HarmonyOS 效能最佳化
- oracle 效能最佳化Oracle
- MethodImpl最佳化效能
- 前端效能最佳化前端