2015/04/25

FireDAC dbExpress 效能之戰,使用DataSnap

打從接觸dbExpress(以下簡稱DBX)開始,對於DBX能否應用在實戰當中存在非常大的疑問。

但是ADO和FireDAC是屬於2-Tier架構元件,要和DBX這種屬於單向唯讀的元件比較,由於立足點不同,所以直接比較是非常奇怪的事情。

也許使用While Loop測試比較也可以;但測試結果與其說是測元件效能,說是測試電腦硬體效能應該更為貼切。

While not Query.Eof do
begin
  Query.FieldByName(FieldName).AsString...
  Something code...
  Query.Next();
end;

這樣的應用,現實設計卻很少在我們的專案中出現。
那麼這樣的測試方法,存在有以下兩點問題:

  1. 並非屬於收集資料集合的特殊演算法,Cursor的操作偏重在硬體處理,效能不佳。
  2. 背離經常使用的實際程式設計方法,為了測試而測試,對實戰並沒有幫助。 
基於上述的理由,必須把所有元件拉到同一條水平線進行測試才有意義。

既然要測試,就要來想想,要測試的目的是什麼,為了什麼而測試。

BDE後的繼承者有ADO、DBX和FireDAC,以下是開發者面對開發技術所關心的議題:

穩定性:

圖片來源:3lian
最讓開發者關心的是穩定,ADO的穩定性在業界口碑中是穩居第一名,但現已不再受Delphi維護。

DBX發展至今已經進入維護期,據說有潛在的BUG。

FireDAC是AnyDAC的產物,能夠被EMBT買下可證明這元件組的穩定性是有它的水平在。

效能、速度:

圖片來源:ItsFoss
ADO是Windows平台下的產物,有它的品質保證在。
DBX,自它誕生以來一直被吹捧著它的效能,但實際上一直沒有人明確證明這件事情。
FireDAC,隨著XE5下正式進入開發市場,效能也是官方掛保證,但也沒有看到有人來證實它的效能。

開發方便性:

圖片來源:RSI Concepts
ADO雖然被封裝得很好,但為了配合ADO的框架,間接導致與其它資料集元件設計方式有所出入;最經典的便是ADO的TParameters和BDE等其它資料集元件的TParams不同了。

DBX維持著和BDE相同開發方式,但其單向唯讀的特性,以及必須搭配DataSnap元件(TDataSetProvider, TClientDataSet),開發便利性因而打了點折扣。

FireDAC已被推為是主力的資料集元件,和BDE的連結度也最高,但新奇的連結資料庫設計方式,要再重新熟悉是唯一的門檻。

當然還有其它理由,但經常聽到的就是「穩定、效能、方便」這三項。

如何測試?

要測試前,先來看看要如何才能夠滿足需求點。
  1. 不用寫Code,方便。
  2. 任何SQL語法都要能被元件轉譯給Database正確載入及回傳資料集合。
  3. 能夠正確更新異動欄位,當然,能不寫SQL就不寫。
滿足上述三點的工作,其實就是:
  • TDataSet.Open
  • TDataSet.Append;
  • TDataSet.Edit
  • TDataSet.Post
  • TDataSet.Delete
  • TDataSet.ExecSQL
以ADO和FireDAC來說,這都辦得到。
唯獨DBX,它還必須搭配DataSnap元件組才能完成……

那麼,如果ADO和FireDAC也搭配DataSnap,這樣這三個元件組就能站在同一個水平線上比較了。

使用DataSnap元件組測試也有幾個好處:
  • 不用自己寫程式去讀取每一條Record。
  • 不用自己寫程式去更新異動。
  • 一律採用批次更新。

DataSnap要做到上述幾點,關鍵在控制元件,也就是ADO、DBX、FireDAC等。
而在它們的核心,便是ADO Provider Driver、DBX Driver、FireDAC Library。

ADO Provider Driver是由Mircosoft提供,已不再更新。
FireDAC Library是由EMBT官方維護。
DBX Driver,因為Borland的策略,所以它除了官方維護外,還有3rd Party可以提供支援。

ADO,因為它搭配DataSnap,在實際設計時有物件轉換上的麻煩。故本次便不把它列入測試項目。

DBX除了官方DBX4 Driver可以選擇之外,還有Devart DBX Driver可以選擇。

於是最終測試所參與的元件組有:
  • EMBT FireDAC for SQL Server
  • EMBT DBX4 driver for SQL Server
  • Devart DBX drvier for SQL Server

接著是,由於目標是測試Driver處理資料的速度,於是像DBGrid等DB Aware元件就不納入使用,以免測試時間過長。

Round 1: SELECT

在2-Tier架構下,TDataSetProvider是直接連結TClientDataSet,這一段轉換時間是固定的,所以Driver如何轉換到TDataSetProvider.Data是勝負關鍵。

TClientDataSet.PacketRecords設為-1,確保所有資料會完全下載到TClientDataSet。

我找了一個含有複合欄位,包含了有varchar, nchar, nvarchar, text等長度不一的資料表。
一共有20368筆資料,以下是ClientDataSet.Open所花的時間比較結果。

ClientDataSet.Open完成所需的時間
很意外的,EMBT DBX4在這個項目中所花費的時間平均都在「40秒」 以上。
Devart DBX和FireDAC各別是「3.096秒」和「2.906秒」;兩者差距僅在0.01秒之間,效能非常接近。
然而EMBT DBX4的表現相對遜色非常多,這注定了它不被採用的致命傷。

※※※※※※※※※※※※※※※※※※※
在這個測試還發現EMBT DBX4有一個已知且無解的問題:Nchar/Nvarchar Size * 2。
EMBT DBX4在識別Nchar/Nvarchar時,欄位長度會被放大2倍

FireDAC及Devart DBX都不會有Nchar/Nvarchar欄位長度被放大2倍的問題。
FireDAC and Devart DBX will not size * 2 with Nchar/Nvarchar. 
※※※※※※※※※※※※※※※※※※※

我在進入Round 2測試前,會建立一個暫存資料表,並建立三個欄位,SQL如下:
CREATE TABLE MyTest(A1 nchar(50) primary key, A2 nchar(50), A3 nchar(50))

Round 2: Append

先使用Loop Append建立1000筆資料後,計算ClientDataSet.ApplyUpdate開始到結束所花費的時間。
這樣可以交由DataSetProvider利用DataSet Driver自動產出Append SQL,此方式很適合有批次大量更新的場合來參考。

ClientDataSet.Append ApplyUpdate完成所需的時間
Devart DBX 在這個階段中以「0.875秒」勝出,EMBT DBX4則是「0.953秒」緊追在後。
FireDAC則是以「1.609秒」落後DBX一個單位(0.5秒)。

Round 3: Update

在Round 2: Append階段完成後,接著就是對那1000筆資料進行編輯,並計算其ApplyUpdate開始到完成所花費的時間。
ClientDataSet.Update ApplyUpdate完成所需的時間
EMBT DBX4在Update階段表現得非常亮眼,僅花了「0.718秒」的時間。
Devart DBX用了「1.062秒」,仍是低於FireDAC「2.016秒」近兩個單位。

Round 4: Delete

最後,把已建立的1000筆資料刪除,並計算其ApplyUpdate開始到完成所花費的時間。
ClientDataSet.Delete ApplyUpdate完成所需的時間
Devart DBX和EMBT DBX4的效率依然在伯仲之間,而FireDAC落後了一個單位。

總結:

雖然EMBT DBX4在Append、Update、Delete有相對效佳的效能,但品質穩定性在SELECT下大打折扣,除了Open時間非常久之外,某些SQL居然還有不相容而導致無法Open的情形。
所以EMBT DBX4在SQL Server下建議還是不要採用。

在排除EMBT DBX4後,最終變成是Devart DBX和FrieDAC的效能之戰。
Devart DBX在SELECT下和FireDAC只有微小的差距,但Append、Update、Delete全都大勝FireDAC,可見Devart在Provider Driver有多費心的調教。

再回頭看一下設計畫面:
FireDAC + DataSnap設計畫面

Devart DBX + DataSnap設計畫面
就設計方便性來看,我認為DBX在DataSnap框架上是非常簡約的!

要評估DataSnap方案時,投資個對自己有利的對策吧。

Devart DBX for SQL Server,真的是很優秀的解決方案!



傳送門:Devart dbExpress Driver for SQL Server

3 則留言:

  1. 可否將您測評的專案放出來參考呢?或放到delphi.ktop.com.tw?

    回覆刪除
  2. 您的測試讓我老頭我又得放緩使用FireDac的脚步了,我用Devart DbExpress Driver多年了,每次看到dataset->dataprovider->clientdataset->datasource 多起來時心中就害怕。才想著轉用FireDac呢.......唉 日落西片 有時真的感覺會累的。
    還是要感謝您的測試,畢竟Delphi圈圈不大,有能力有熱情的傑出人士很珍稀的,給你大大的掌聲!!!

    回覆刪除
  3. 網誌管理員已經移除這則留言。

    回覆刪除