很多演算法都會產生落地的中間結果,從而影響效能,尤其是資料量較大的時候。這種情況下通常可用程式游標來避免資料落地,下面舉例說明。
計算目標:訂單表原來已按時間排序,需要將資料按日期、產品去除重複,再統計記錄條數。
由於去重後結果集較大,記憶體放不下,因此一般會用groupx去重,spl指令碼如下:a1
=file("sales.btx").cursor@b()
/從集檔案讀入訂單記錄
2=a1.groupx(date(orderdate),productid)
/按日期、產品分組去重
3=a2.skip()
/對游標計數
但函式groupx會導致資料落地,因此效能不高。
要使去重的中間結果不落地,可以先生成程式游標,distinctproduct.dfx指令碼如下:ab
1=file("sales.btx").cursor@b()
2for a1;date(orderdate)
=a2.id(productid)
3return b2
a2:迴圈訂單表。由於資料已按時間排序,因此每次取日期相同的一批數。
b2:按產品去重。注意,全量資料雖大,但按天取數相對較少,記憶體可以放下,所以這裡用id去重。
主程式可通過cursor函式呼叫程式游標,用法與普通游標類似:a1
=cursor("distinctproduct.dfx")
/呼叫程式游標
2=a1.skip()
可以看到,程式游標可減少資料落地,從而提公升計算效能。
資料庫進行集合運算時要先排序,如果資料量太大,則排序會耗費大量時間,遲遲不能輸出結果。在這種情況下,適合用程式游標生成不落地的有序中間結果集,從而實現快速輸出。
比如兩張結構相同表:callrecorda、callrecordb。兩張表在時間欄位calltime上建立了索引,每秒資料量萬級,現在對2015-01-01這一天的資料做並集運算,需要快速輸出前500條(比如在報表上快速呈現)。
這次將程式游標和呼叫**寫在同乙個指令碼中,如下:ab
c1func
=connect("orcl")
2for 60*60*24
=elapse(datetime("2015-01-01 00:00:00"),a2-1)
3=a1.query("select calltime,outid,inid,duration,charge from"+a1+"where calltime=?",b2)
4=b3.sort(outid,inid,duration,charge)
5return b4
6=a1.close()
7=cursor@c(a1,"callrecorda")
8=cursor@c(a1,"callrecordb")
9=[a7,a8].mergex@u()
10=a9.fetch@x(500)
a1:用func定義程式游標,相應的呼叫語法為cursor@c。
b2:迴圈一天中的每一秒。
c3:從資料庫查詢一秒的資料,因為是按索引取數,所以速度很快,而且對資料庫影響很小。注意a1是表名變數,程式游標既可以從callrecorda取數,也可以從callrecordb取數。
c4:對一秒資料進行記憶體排序,以便形成有序結果集。由於資料在同一秒,所以只需對其他字段排序。
a7a8:以表名為引數,取出2個程式游標。
a9:對兩個游標進行有序歸併,@u表示取並集。類似地,可以用@i和@d分別進行並交集、差集運算。
Oracle SQL 效能優化技巧
sun2004發表於 2008 12 25 11 28 眾所周知,資料庫設計的好壞直接關係到資料庫執行的效率。根據筆者的經驗,對於提公升資料庫效能來說,合理的資料庫設計,比公升級伺服器的硬體配置,還要來的有效。但是,筆者無論是在跟同事合作,又或者是在論壇上跟相關同行交流的時候,總是會發現有些人有一些...
Apache效能優化技巧
本文出自 本文簡要介紹了幾個優化 apache 的技巧,在實戰中十分有用。公升級 apache 到最新版本,新版本往往包含效能提公升和安全更新。在 httpd.conf 中設定 hostnamelookups off 能避免針對每個訪問者的 dns 網域名稱的反向查詢。採用另外一台伺服器處理檔案。保...
PHP 效能優化技巧
google 在 google code 製作了 let s make the web faster 讓我們使得 web 更快 的 中,分享了一些如網頁效能優化的技巧和教程以及工具,今天我就翻譯一篇技巧文章 php 效能優化技巧,他說的5條技巧我都不知道。1.不要隨便就複製變數有時候為了使 php ...