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

【BCB】【問題】用DBGrid一次顯示大量資料很慢

尚未結案
taisun
一般會員


發表:10
回覆:8
積分:3
註冊:2005-08-22

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-09-09 02:01:23 IP:163.28.xxx.xxx 未訂閱
大家好,我的問題是我的資料庫有17萬筆資料,當用DBGrid一次顯示全部資料時前置作業時間會很慢(Open),即使我只選一個欄位也一樣,我已經試過用BDE: TTable+TDataSetProvider+TClientDataSet+TDataSet+DBGrid,也是過用ADOQuery,時間都差不多一樣慢,小弟已經在本論壇爬文過很多資料,也得知蠻多人遇到這個問題,我是模仿另一套別人開發的軟體去做,看完本論壇文章後心想顯示大量資料慢當然是正常的,但令人生氣的是那套別人寫的軟體,只要花不到一秒的時間就可以把這17萬筆用長得很像DBGrid的東西顯示出來,他開發的環境我猜不出來,可能是Virtual FoxPro吧(純猜測),偏偏我用BCB不論用ADO或BDE就要半分鐘,更扯的是我開完資料庫程式大約吃了150MB記憶體以上,但別人的程式吃記憶體卻不超過10MB,請問這樣的差異是為什麼呢?難道BCB這兩種元件的能力就這樣嗎?    PS1:所讀的資料庫是dbf檔(FoxPro),程式都在本機執行。 PS2:他的Grid一開出來我就能拉到最後一筆去,若我用PacketRecords設定開啟Grid可以不用一秒,但拉到最後一筆去一樣花了半分鐘.... < >< > PS3:他的程式我確定沒有在開啟主程式時就先偷偷連去那個Table,因為開啟主程式也不用一秒鐘。 發表人 - taisun 於 2005/09/09 02:07:13
malanlk
尊榮會員


發表:20
回覆:694
積分:577
註冊:2004-04-19

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-09-09 08:35:50 IP:203.69.xxx.xxx 未訂閱
我很好奇(因為我沒試過這麼大的DBF), 如果 只是拉ㄧ個 Table, Open Table->Table.First->Table.Last BDE,ADO 各要多久? 可以請 taisun 兄測量一下嗎? Open Table->Table.MoveBy(10000)->...->until Table.Eof BDE,ADO 各要多久? 可以麻煩 taisun 兄再測量一下嗎? 我的意思是 拋開顯示元件這一部份, BDE, ADO 操縱Table的能力如何? 這才是所謂的 BDE ADO的能力吧... 170MB 是不是為了暫存資料而產生? 如果是, 可以拋開 DELPHI 的元件, 只用單純的 StringGrid Record Cursor 來控制資料顯示嗎? 從資料讀出, 要Cached 多少筆資料, 到資料顯示出來, 都有技巧, 我想這就是許多付費元件生存的空間吧.
rogan321
高階會員


發表:21
回覆:307
積分:200
註冊:2003-05-15

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-09-09 12:55:48 IP:220.130.xxx.xxx 未訂閱
那是因為事實上該軟體並沒有將資料全部傳回 只是傳回畫面上需要用到的資料~否則記憶體再多都會爆掉~ ~利如控制MaxRecords的大小~ 或則自已控制傳回筆數~在grid有變動時~在call一次query
taisun
一般會員


發表:10
回覆:8
積分:3
註冊:2005-08-22

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-09-10 12:31:54 IP:163.28.xxx.xxx 未訂閱
引言: 那是因為事實上該軟體並沒有將資料全部傳回 只是傳回畫面上需要用到的資料~否則記憶體再多都會爆掉~ ~利如控制MaxRecords的大小~ 或則自已控制傳回筆數~在grid有變動時~在call一次query
嗯原來如此阿,再經過我試驗過後,發現也是利用的元件的關係: 以下皆用DBE: 1.Table DataSetProvider ClientDataSet DataSource 當ClientDataSet->Open並顯示在DBGrid上,時間需半分鐘,消耗記憶體120MB以上。 應該是像rogan321大大所指示的全部傳回吧。 2.Table DataSource 當Table->Open並顯示在DBGrid上,時間不用一秒鐘,記憶體只消耗 20MB左右(幾乎沒增加)。 因此Table這個元件本身會控制傳回筆數吧,所以目前的作法是採用2.所以效能上好很多, 不過若要用到複雜的查詢還是要用1.吧(或Query),只是就要自己控制回傳資料囉。(應該是這樣吧rogan321大大)
taisun
一般會員


發表:10
回覆:8
積分:3
註冊:2005-08-22

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-09-10 12:32:38 IP:163.28.xxx.xxx 未訂閱
引言: 那是因為事實上該軟體並沒有將資料全部傳回 只是傳回畫面上需要用到的資料~否則記憶體再多都會爆掉~ ~利如控制MaxRecords的大小~ 或則自已控制傳回筆數~在grid有變動時~在call一次query
嗯原來如此阿,再經過我試驗過後,發現也是利用的元件的關係: 以下皆用DBE: 1.Table DataSetProvider ClientDataSet DataSource 當ClientDataSet->Open並顯示在DBGrid上,時間需半分鐘,消耗記憶體120MB以上。 應該是像rogan321大大所指示的全部傳回吧。 2.Table DataSource 當Table->Open並顯示在DBGrid上,時間不用一秒鐘,記憶體只消耗 20MB左右(幾乎沒增加)。 因此Table這個元件本身會控制傳回筆數吧,所以目前的作法是採用2.所以效能上好很多, 不過若要用到複雜的查詢還是要用1.吧(或Query),只是就要自己控制回傳資料囉。(應該是這樣吧rogan321大大)
taisun
一般會員


發表:10
回覆:8
積分:3
註冊:2005-08-22

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-09-10 12:44:23 IP:163.28.xxx.xxx 未訂閱
引言: 我很好奇(因為我沒試過這麼大的DBF), 如果 只是拉ㄧ個 Table, Open Table->Table.First->Table.Last BDE,ADO 各要多久? 可以請 taisun 兄測量一下嗎? Open Table->Table.MoveBy(10000)->...->until Table.Eof BDE,ADO 各要多久? 可以麻煩 taisun 兄再測量一下嗎? 我的意思是 拋開顯示元件這一部份, BDE, ADO 操縱Table的能力如何? 這才是所謂的 BDE ADO的能力吧... 170MB 是不是為了暫存資料而產生? 如果是, 可以拋開 DELPHI 的元件, 只用單純的 StringGrid Record Cursor 來控制資料顯示嗎? 從資料讀出, 要Cached 多少筆資料, 到資料顯示出來, 都有技巧, 我想這就是許多付費元件生存的空間吧.
To: malanlk 大大 原來就像你講的,用Table很快ㄚ,是小弟本身用元件的關係,至於原本我會這樣連結,而不直接用Table DataSource也是看到書上這樣用,沒去想太多就直接照抄啦,現在兩位大大應該都算有得分,可是只能選一位阿,所以就給回答較明確的rogan囉
taisun
一般會員


發表:10
回覆:8
積分:3
註冊:2005-08-22

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-09-10 13:00:29 IP:163.28.xxx.xxx 未訂閱
引言: 那是因為事實上該軟體並沒有將資料全部傳回 只是傳回畫面上需要用到的資料~否則記憶體再多都會爆掉~ ~利如控制MaxRecords的大小~ 或則自已控制傳回筆數~在grid有變動時~在call一次query
請問一下,我又試了ADOTable,結果也是花了很久的時間,或許是ADOTable沒像TTable那樣效率好‧ 另外再請問一個問題rogan大大,我很好奇若是用Query物件,你說當grid變動時再call一次query,這樣怎麼做到讓Dbgrid跑到任意筆數或是最後一筆呢,因為就像我用1.的方式,只要一呼叫query->MoveLast(),一樣會跑很慢,感覺又回傳所有資料了。難道我要下更嚴格的Select條件讓他Record筆數變少,到底要怎麼做只傳回固定筆數,卻又可以任意跳到我要的資料呢?
rogan321
高階會員


發表:21
回覆:307
積分:200
註冊:2003-05-15

發送簡訊給我
#8 引用回覆 回覆 發表時間:2005-09-11 09:15:38 IP:219.68.xxx.xxx 未訂閱
1.資料量大~用Table效率上原則一定比query慢~但這又和你的資料庫有關~paradox這種file形態的db用table就是比query快~但是table是將資料全部傳回在進行filter的動作來取出需要的資料~所以大量的資料鐵定不適用~ 2.那如果用query~就需要動一些手腳了~雖然只傳回顯示的資料量~但是也要先得知整個資料庫的筆數,這不難得知~然後將資料集切割成幾個等份~當顯示的範圍是在此等份之間即直接從memery取得否則即再次下query再從db傳回~顯示於grid上面 這裡或許直接用stringgrid或grid來做即可~用dbgrid反而不好實做~然後自己控制scrollbar取得目前的等份 還有你說的"沒有在開啟主程式時就先偷偷連去那個Table"用ADOConnection來統一連線也是可以達到此要求~主程式只負責connect的動作~其餘的dataset元件~在有需要連資料庫時都透過adocon~那就不用反覆的建立連線~也浪費記憶體資源
taisun
一般會員


發表:10
回覆:8
積分:3
註冊:2005-08-22

發送簡訊給我
#9 引用回覆 回覆 發表時間:2005-09-11 17:55:43 IP:163.28.xxx.xxx 未訂閱
引言: 1.資料量大~用Table效率上原則一定比query慢~但這又和你的資料庫有關~paradox這種file形態的db用table就是比query快~但是table是將資料全部傳回在進行filter的動作來取出需要的資料~所以大量的資料鐵定不適用~ 2.那如果用query~就需要動一些手腳了~雖然只傳回顯示的資料量~但是也要先得知整個資料庫的筆數,這不難得知~然後將資料集切割成幾個等份~當顯示的範圍是在此等份之間即直接從memery取得否則即再次下query再從db傳回~顯示於grid上面 這裡或許直接用stringgrid或grid來做即可~用dbgrid反而不好實做~然後自己控制scrollbar取得目前的等份 還有你說的"沒有在開啟主程式時就先偷偷連去那個Table"用ADOConnection來統一連線也是可以達到此要求~主程式只負責connect的動作~其餘的dataset元件~在有需要連資料庫時都透過adocon~那就不用反覆的建立連線~也浪費記憶體資源
雖然了解您的意思,但不是很多怎麼切割成某些等份,例如我有100筆資料,剛好分別id是從1~100,若我原本應該是Select * from Table,改成切割兩等份用Select * from table where id < 50,所以顯示資料就變少了,您的意思是這樣控制切割等分嗎?但這樣未必有些時候很好控制條件。
rogan321
高階會員


發表:21
回覆:307
積分:200
註冊:2003-05-15

發送簡訊給我
#10 引用回覆 回覆 發表時間:2005-09-11 22:16:09 IP:219.68.xxx.xxx 未訂閱
引言: 雖然了解您的意思,但不是很多怎麼切割成某些等份,例如我有100筆資料,剛好分別id是從1~100,若我原本應該是Select * from Table,改成切割兩等份用Select * from table where id < 50,所以顯示資料就變少了,您的意思是這樣控制切割等分嗎?但這樣未必有些時候很好控制條件。
當然sql不能寫死~例如 先取得總筆數:MAX()或COUNT()等等 設定幾筆進行切割的動作 例如1000筆(AGV) 那總筆數大於於1時進行切割 records/1000=Value~無條件進入整數 Value不就表示你要切的份數了嗎 例如~切5份 那要第三份不就是 i=3時 Select * from table where id BETWEEN (i-1)*AGV AND ((i*AGV)-1) 目前是要哪一份~可以由你的scrollbar是在哪個i的範圍取得 當scrollbar超出目前資料的範圍時~去QRY~剩下的只是GRID畫面的為裝而已 目標只是讓資料集不是那麼大~緩慢程式的速度~
taisun
一般會員


發表:10
回覆:8
積分:3
註冊:2005-08-22

發送簡訊給我
#11 引用回覆 回覆 發表時間:2005-09-12 09:24:01 IP:163.28.xxx.xxx 未訂閱
引言:
引言: 雖然了解您的意思,但不是很多怎麼切割成某些等份,例如我有100筆資料,剛好分別id是從1~100,若我原本應該是Select * from Table,改成切割兩等份用Select * from table where id < 50,所以顯示資料就變少了,您的意思是這樣控制切割等分嗎?但這樣未必有些時候很好控制條件。
當然sql不能寫死~例如 先取得總筆數:MAX()或COUNT()等等 設定幾筆進行切割的動作 例如1000筆(AGV) 那總筆數大於於1時進行切割 records/1000=Value~無條件進入整數 Value不就表示你要切的份數了嗎 例如~切5份 那要第三份不就是 i=3時 Select * from table where id BETWEEN (i-1)*AGV AND ((i*AGV)-1) 目前是要哪一份~可以由你的scrollbar是在哪個i的範圍取得 當scrollbar超出目前資料的範圍時~去QRY~剩下的只是GRID畫面的為裝而已 目標只是讓資料集不是那麼大~緩慢程式的速度~ < face="Verdana, Arial, Helvetica"> < >< >原來是這樣,謝謝您的指教!
系統時間:2024-11-23 10:10:45
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!