全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1905
推到 Plurk!
推到 Facebook!

TreeView 的資料來自資料庫,使用使用遞迴方式但速度太慢??

尚未結案
jeffreck
高階會員


發表:247
回覆:340
積分:197
註冊:2003-01-23

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-03-12 11:01:33 IP:61.219.xxx.xxx 未訂閱
請教各前輩 TreeView 的資料來自資料庫,使用使用遞迴方式但速度太慢??    我的作法如下:  
 
procedure GetTreeMenu(TreeMenu : TTreeView;ItemID: Integer);
Var
qry : TAdoQuery ;    begin
  qry := TAdoQuery.Create(nil);
  qry.Connection:=SYSData.cnt_SaleTable;
  qry.SQL.Add('SELECT FunctionMenu.* ') ;
  qry.SQL.Add('FROM FunctionMenu ');
  qry.SQL.Add('WHERE FunctionMenu.ItemType=0' );  //系統名稱別
  qry.SQL.Add('And  (' );
  qry.SQL.Add('FunctionMenu.ItemID In( Select ItemID From UserLicense Where '''  
               FunSystem.GetWindowsUserName   ''')' );
  qry.SQL.Add('Or 1=(Select SuperUser From [User] Where '''  
              FunSystem.GetWindowsUserName   ''') ');
  qry.SQL.Add(')' );
  qry.SQL.Add('ORDER BY FunctionMenu.ItemOrder ');
  qry.Open ;       While not Qry.Eof do
  begin
    AddChildNode(TreeMenu,nil, Qry.FieldByName('ItemID').AsInteger  , Qry.FieldByName('ItemCaption').AsString);
    Qry.Next;
  end;
   Qry.Free ;
end;    Function AddChildNode(TreeMenu : TTreeView;Parentnode: TTreeNode; ItemID: Integer ; ItemCaption: string): TTreeNode;
var
  Qry: TADOQuery;
  NoteData : rdMenuData ;    begin
  new(NoteData );
  NoteData.ItemID :=ItemID;
  Result  := TreeMenu.Items.AddChild(Parentnode, ItemCaption);
  Result.data := NoteData;      qry := TAdoQuery.Create(nil);
  qry.Connection:=SYSData.cnt_SaleTable;
  qry.SQL.Add('SELECT FunctionMenu.* ') ;
  qry.SQL.Add('FROM FunctionMenu ');
  qry.SQL.Add('WHERE FunctionMenu.ItemParent='   inttostr(ItemID));  //系統名稱別
  qry.SQL.Add('ORDER BY FunctionMenu.ItemOrder ');      qry.Open ;
  While not Qry.Eof do
  begin        AddChildNode(TreeMenu ,Result, Qry.FieldByName('ItemID').AsInteger  , Qry.FieldByName('ItemCaption').AsString);
    Qry.Next;      end;
  Qry.Free;
 // NoteData := nil ;    end;    
不知是否還可以改善的空間,還是資料結構修改?? 非常非常的謝謝你,因為有你這世界變的更美好 ☆ ^_^ ☆ °∴°﹒☆°.﹒‧°∴°﹒°.﹒‧°∴°﹒ ﹒‧°∴°﹒☆°.﹒‧°∴°﹒°.﹒‧°∴°﹒﹒‧°∴°﹒☆
Fishman
尊榮會員


發表:120
回覆:1949
積分:2163
註冊:2006-10-28

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-03-12 11:29:35 IP:210.65.xxx.xxx 未訂閱
Hi jeffreck,    timhuang 大大的建議,未展開的先不 load db 是否適用?    http://delphi.ktop.com.tw/topic.php?TOPIC_ID=44484 ---------------------------------- 小弟才疏學淺,若有謬誤尚請不吝指教 ----------------------------------
------
Fishman
jeffreck
高階會員


發表:247
回覆:340
積分:197
註冊:2003-01-23

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-03-12 19:07:43 IP:61.219.xxx.xxx 未訂閱
引言: Hi jeffreck, timhuang 大大的建議,未展開的先不 load db 是否適用? http://delphi.ktop.com.tw/topic.php?TOPIC_ID=44484 ---------------------------------- 小弟才疏學淺,若有謬誤尚請不吝指教 ---------------------------------- < face="Verdana, Arial, Helvetica"> 謝謝前輩回覆 但我的程式如想一次全部載入 不知是否有更好的方法 我在想因該是慢在作Query 的動作,所以在那有何方法可以只作一次Query ?? 謝謝
Mickey
版主


發表:77
回覆:1882
積分:1390
註冊:2002-12-11

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-03-13 12:01:04 IP:218.32.xxx.xxx 未訂閱
jeffreck 你好: 一定要 Load 全部的 Data, 倒是可以考慮用 ClientDataSet Load Data 後, 運用 Index / Filter Property 來建立 TreeView.
jeffreck
高階會員


發表:247
回覆:340
積分:197
註冊:2003-01-23

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-03-13 23:23:19 IP:61.70.xxx.xxx 未訂閱
引言: jeffreck 你好: 一定要 Load 全部的 Data, 倒是可以考慮用 ClientDataSet Load Data 後, 運用 Index / Filter Property 來建立 TreeView.
原來還可以用ClientDataSet ,我沒有用過這元件, 但有找到一些資料我來試試看 另外請教如使用 ClientDataSet 那資料載入後, 原本在 ms sql 中的Index還有作用嗎??
TATSU
版主


發表:50
回覆:135
積分:62
註冊:2003-01-16

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-03-14 04:04:29 IP:203.218.xxx.xxx 未訂閱
為了要上載檔案,我開了一個新主題: http://delphi.ktop.com.tw/topic.php?TOPIC_ID=46469 這一個例子是根據 Fishman 的例子 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=44484 而建的,主要是減低開 query 的次數,改由 loop 去讀取 TList 內的資料: 方法(一)跟 Fishman 的做法相同。 方法(二)則有所改變,第一層的 menu 直接由 table 讀出,以後的一次過由 query 讀出,先建設一個 TList 存放,然後一層層放入 TreeView。 方法(三)是將方法(二)稍作改動,將已加入 TreeView 的 TList item 刪除,減少 loop 的次數。這一個方法未必可以真正增加速度,因為程式多花了時間去比較一些已加入的資料,要運作一個 loop 去刪除那些資料。 但這個例子的資料數量還是太少,我未知數量大的 table 運作時的情況,更不知你的 menu 數量,你可以自己測試三個方法的速度。
jeffreck
高階會員


發表:247
回覆:340
積分:197
註冊:2003-01-23

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-03-14 14:44:34 IP:61.219.xxx.xxx 未訂閱
謝謝 Mickey 前輩提供的 ClientDataSet 方法 我目前使用ClientDataSet產生檔案存入Client端 之後再用 ClientDataSet 的 Filter 來取資料 這樣速度快很多了,謝謝....    ------------------------------------------------------ 謝謝 TATSU 前輩提供的方法 真想不到還有這種方法!! 目前正在努力學習中............... < >真不知如何給分< >
TATSU
版主


發表:50
回覆:135
積分:62
註冊:2003-01-16

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-03-14 16:07:04 IP:203.218.xxx.xxx 未訂閱
其實你的 TABLE 內存放多少筆 menu 的資料?
jeffreck
高階會員


發表:247
回覆:340
積分:197
註冊:2003-01-23

發送簡訊給我
#9 引用回覆 回覆 發表時間:2004-03-14 21:35:14 IP:61.70.xxx.xxx 未訂閱
引言: 其實你的 TABLE 內存放多少筆 menu 的資料?
資料目前為500多筆 謝謝
TATSU
版主


發表:50
回覆:135
積分:62
註冊:2003-01-16

發送簡訊給我
#10 引用回覆 回覆 發表時間:2004-03-14 22:07:17 IP:203.218.xxx.xxx 未訂閱
那不算太多資料,快的半秒內完成,慢的一秒半左右的事,如果超過二千筆,可以再試驗其他方法。
jeffreck
高階會員


發表:247
回覆:340
積分:197
註冊:2003-01-23

發送簡訊給我
#11 引用回覆 回覆 發表時間:2004-03-15 18:26:58 IP:61.219.xxx.xxx 未訂閱
引言: 那不算太多資料,快的半秒內完成,慢的一秒半左右的事,如果超過二千筆,可以再試驗其他方法。
測試結果報告: 我又加了一個方案四:用ClientDataSet產生檔案存入Client端 之後再用 ClientDataSet 的 Filter 來取資料 結果如下:: 資料庫使用MS SQL 470筆 第一次 方案一:55.108秒 方案二:0.343秒 方案三:1.750秒 方案四:3.46秒 第二次 方案一:55.249秒 方案二:0.328秒 方案三:0.375秒 方案四:2.87秒 15040筆 方案一:跑了二個小時還沒出來,決定不等了... 方案二:1分27.46秒 方案三:1分25.203秒 方案四:跑了30分還沒出來,決定不等了... TATSU 真是高手< >< >
TATSU
版主


發表:50
回覆:135
積分:62
註冊:2003-01-16

發送簡訊給我
#12 引用回覆 回覆 發表時間:2004-03-15 19:29:20 IP:203.218.xxx.xxx 未訂閱
jeffreck 兄,其實程式還有多少改良的空間,你試試。    你見到程式碼中有一段在 loop 裏再一次要走到 query 的 record number 抓資料嗎?如果在前一段一早讀入,這一個再抓資料的動作都可以刪除。當然,那個 TList 內的資料架構要先更改去載入那些 menu 的名稱及 description 。其實程式一早已經要讀取 menu 及 parent 的 id,何不一次過再讀取其他的資料。    另一方面,你可以參考: 將這個 query 由:
  qryMenu.SQL.Add('SELECT * FROM MENU '  
                  'WHERE PARENT_MENU_ID > 0 '  
                  'ORDER BY PARENT_MENU_ID, MENU_ID, SEQNO') ;
改成這樣
  qryMenu.SQL.Add('SELECT * FROM MENU '  
                  'WHERE PARENT_MENU_ID > 0 '  
                  'ORDER BY PARENT_MENU_ID DESC, MENU_ID DESC, SEQNO DESC') ;
運行 loop 時也要逆行
    for i := 0 to (aMenuList.Count - 1) do 
改成:
    for i := (aMenuList.Count - 1) downto 0 do 
loop 的最後加上以下的一段,原來那個用來刪除已經加入 Treeview 的 loop 就刪除,你又試試是否可以令速度再提昇。
      Dispose(PQryMenuRec(aMenuList.Items[i])) ;
      aMenuList.Delete(i);    
這個供你參考,如果你有需要,我可以修改那個程式,再給你試,你也可以根據以上資料去做。
TATSU
版主


發表:50
回覆:135
積分:62
註冊:2003-01-16

發送簡訊給我
#13 引用回覆 回覆 發表時間:2004-03-16 12:49:38 IP:203.218.xxx.xxx 未訂閱
http://delphi.ktop.com.tw/topic.php?TOPIC_ID=46570 jeffreck 兄,有一個新的測試速度程式,你可以再試試,內裡有更詳細的講解。
pcplayer99
尊榮會員


發表:146
回覆:790
積分:632
註冊:2003-01-21

發送簡訊給我
#14 引用回覆 回覆 發表時間:2004-06-12 15:37:11 IP:219.133.xxx.xxx 未訂閱
引言: http://delphi.ktop.com.tw/topic.php?TOPIC_ID=46570 jeffreck 兄,有一個新的測試速度程式,你可以再試試,內裡有更詳細的講解。
如果总共只有1-2千条,不如直接一次把全部Record抓进来,排序后直接处理。比每一条都去从DataBase用select 来取更快。
shioulo
一般會員


發表:1
回覆:5
積分:1
註冊:2002-05-30

發送簡訊給我
#15 引用回覆 回覆 發表時間:2004-06-13 19:32:32 IP:61.66.xxx.xxx 未訂閱
TreeView for DB 的設計, 個人是用來作製程管理 就目前使用資料庫內資料超過20萬筆, 載入任一專案全部資料均不到2秒 專案資料若一千筆, 也可約10秒完成. 提供設計建議 資料載入分單層載入與全部兩種設計模式, 當一層一層進入時, 則速度會相當快 , 若需要一次全部展開tree, 則一次將該專案資料一次取出然後再放到tree上 這樣就可以有較好的效率展現
系統時間:2024-05-18 17:10:12
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!