2013-05-08 121 views
1

循環我有一個代碼,一些這樣的事通過優化數據集

dxMemOrdered : TdxMemData; 
while not qrySandbox2.EOF do 
    begin 
     dxMemOrdered.append; 
     dxMemOrderedTotal.asCurrency := qrySandbox2.FieldByName('TOTAL').asCurrency; 
     dxMemOrdered.post; 
     qrySandbox2.Next; 
    end; 

這個代碼在一個線程中執行。當有大量記錄說「400000」時,大約需要25分鐘來解析它。有沒有什麼辦法可以通過優化循環來縮小尺寸?任何幫助,將不勝感激。

更新

基礎上的建議,我做了以下修改

dxMemOrdered : TdxMemData; 
qrySandbox2.DisableControls; 
while not qrySandbox2.Recordset.EOF do 
    begin 
     dxMemOrdered.append; 
     dxMemOrderedTotal.asCurrency := Recordset.Fields['TOTAL'].Value; 
     dxMemOrdered.post; 
     qrySandbox2.Next; 
    end; 
qrySandbox2.EnableControls; 

和我的輸出時間從15分鐘到2分鐘提高。謝謝你們

+1

這是TdxMemData – Jeeva 2013-05-08 08:47:22

+2

使用'try..finally'塊作爲@whosrdaddy在他的答案。我提到的前向遊標可能會幫助您改進從源數據集中讀取數據。 – TLama 2013-05-08 11:59:43

回答

2

一些想法在性能增益VS工作,以便通過你做:

1)檢查,如果您正在使用的SQL方言,您可以使用直接從/ INSERT到SELECT查詢。這取決於你使用的數據庫。

2)確保,如果你的數據集未連接到可視控件,您致電解決這個循環

3 DisableControls/EnableControls)這個代碼必須在程序主線程中運行?也許你可以發送一個單獨的線程,而用戶/程序繼續執行其他操作。

4)當你必須處理真正的大數據時,批量插入是要走的路。許多數據庫都有從文本文件批量插入數據的選項。首先寫入文本文件,然後批量插入比單獨插入更快。再次,這取決於你的數據庫類型。

[編輯:我只是看到你插入信息,它是TdxMemData,所以其中一些不再適用。你已經穿線了,錯過了;-)。我將這些建議留給其他類似問題的讀者]

+0

OP已經使用了一個線程。所以對於這個問題仍然有效的唯一一點是在我的觀點2中。但除了第2點,你可能會建議使用某種只讀向前遊標(取決於數據庫)。 [+1] – TLama 2013-05-08 08:56:57

+0

用答案更新了我的問題。 – Jeeva 2013-05-08 10:26:31

+0

@Jeeva,你也有通過dxMemOrdered鏈接的控件嗎? – whosrdaddy 2013-05-08 10:55:26

2

沒有看到更多的代碼,我唯一可以做的建議是確保任何正在使用內存表的可視化控件都被禁用。假設你有一個名爲Grid cxgrid鏈接到您的dxMemOrdered內存表:

var  
    dxMemOrdered: TdxMemData; 
... 

Grid.BeginUpdate; 
try 
    while not qrySandbox2.EOF do 
    begin 
    dxMemOrdered.append; 
    dxMemOrderedTotal.asCurrency := qrySandbox2.FieldByName('TOTAL').asCurrency; 
    dxMemOrdered.Post; 
    qrySandbox2.Next; 
    end; 
finally 
    Grid.EndUpdate; 
end; 
+0

所以這同樣的規則適用於甚至解析TdxMemData?或者我們應該怎麼做 – Jeeva 2013-05-09 11:18:58

0

這是更好的讓SQL做的工作,而不是迭代雖然在Delphi中循環。嘗試查詢如

insert into dxMemOrdered (total) 
select total from qrySandbox2 

'total'是dxMemOrdered中唯一的字段嗎?我希望它不是主鍵,否則你可能會發生碰撞,這意味着行不會被添加。

+2

這不會工作,因爲dxMemOrdered是一個Tdxmemdata組件(inmemory表) – whosrdaddy 2013-05-08 12:54:13

0

實際上你可以做很多事情來加速你的線程。

第一是看問題更廣泛的角度:

  • 我是不是從緩存/快盤,內存可能是移動中獲取數據?

  • 我正在做正確的事情,當手動彙總總計?SQL引擎特別針對這些問題進行了優化,您只需要定義一個額外的邏輯字段來存儲SQL聚合結果。

,可能對大量的循環帶來的另一個改進小優化是不使用結構,如:

  • Recordset.Fields [「總」]值

  • 記錄.FieldByName('TOTAL')。值

但添加字段的字段編輯器然後直接訪問正確的字段。您將通過字段集合保存整個循環,否則每個字段都會在每個下一個記錄上執行。