TreeView 的資料來自資料庫,使用使用遞迴方式但速度太慢?? |
尚未結案
|
jeffreck
高階會員 發表:247 回覆:340 積分:197 註冊:2003-01-23 發送簡訊給我 |
請教各前輩
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 發送簡訊給我 |
Hi jeffreck, timhuang 大大的建議,未展開的先不 load db 是否適用? http://delphi.ktop.com.tw/topic.php?TOPIC_ID=44484 ----------------------------------
小弟才疏學淺,若有謬誤尚請不吝指教
----------------------------------
------
Fishman |
jeffreck
高階會員 發表:247 回覆:340 積分:197 註冊:2003-01-23 發送簡訊給我 |
引言: 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 發送簡訊給我 |
|
jeffreck
高階會員 發表:247 回覆:340 積分:197 註冊:2003-01-23 發送簡訊給我 |
|
TATSU
版主 發表:50 回覆:135 積分:62 註冊:2003-01-16 發送簡訊給我 |
為了要上載檔案,我開了一個新主題:
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 發送簡訊給我 |
|
TATSU
版主 發表:50 回覆:135 積分:62 註冊:2003-01-16 發送簡訊給我 |
|
jeffreck
高階會員 發表:247 回覆:340 積分:197 註冊:2003-01-23 發送簡訊給我 |
|
TATSU
版主 發表:50 回覆:135 積分:62 註冊:2003-01-16 發送簡訊給我 |
|
jeffreck
高階會員 發表:247 回覆:340 積分:197 註冊:2003-01-23 發送簡訊給我 |
引言: 那不算太多資料,快的半秒內完成,慢的一秒半左右的事,如果超過二千筆,可以再試驗其他方法。測試結果報告: 我又加了一個方案四:用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 發送簡訊給我 |
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 doloop 的最後加上以下的一段,原來那個用來刪除已經加入 Treeview 的 loop 就刪除,你又試試是否可以令速度再提昇。 Dispose(PQryMenuRec(aMenuList.Items[i])) ; aMenuList.Delete(i);這個供你參考,如果你有需要,我可以修改那個程式,再給你試,你也可以根據以上資料去做。 |
TATSU
版主 發表:50 回覆:135 積分:62 註冊:2003-01-16 發送簡訊給我 |
http://delphi.ktop.com.tw/topic.php?TOPIC_ID=46570 jeffreck 兄,有一個新的測試速度程式,你可以再試試,內裡有更詳細的講解。
|
pcplayer99
尊榮會員 發表:146 回覆:790 積分:632 註冊:2003-01-21 發送簡訊給我 |
引言: http://delphi.ktop.com.tw/topic.php?TOPIC_ID=46570 jeffreck 兄,有一個新的測試速度程式,你可以再試試,內裡有更詳細的講解。如果总共只有1-2千条,不如直接一次把全部Record抓进来,排序后直接处理。比每一条都去从DataBase用select 来取更快。 |
shioulo
一般會員 發表:1 回覆:5 積分:1 註冊:2002-05-30 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |