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

執行Query1.Last()速度很慢很慢.

答題得分者是:aven.ko
brook
資深會員


發表:57
回覆:323
積分:371
註冊:2002-07-12

發送簡訊給我
#1 引用回覆 回覆 發表時間:2010-08-30 14:05:20 IP:60.251.xxx.xxx 訂閱
請教各位大大:
1.我用WINXP,Delphi2010,DBMaker3.7.
2.資料筆數約2萬筆.
3.我拉一個TDataBase,TQuery,TDataSource,TDBGrid,及兩個TButton.
4.當我按Button1,執行約2秒,再按Button2時卻要60幾秒.
5.TQuery改成TTable,按Button2只花不到1秒,兩者速度為何差如此大呢?.
6.請教各位大大,我該往哪方面測呢?我測過BCB4,BCB5,BCB6,BCB2010也是同樣結果?


[code delphi]
請在此區域輸入程式碼
procedure TForm1.Button1Click(Sender: TObject);
begin
Query1.SQL.Clear();
Query1.SQL.Add('SELECT * FROM KmOrders');
Query1.Close();
Query1.Open();
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
Query1.Last();
end;
[/code]

P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#2 引用回覆 回覆 發表時間:2010-08-31 09:12:24 IP:118.169.xxx.xxx 未訂閱
你有沒有仔細計算過, 使用 QUERY1.OPEN 與 TABLE1.OPEN 時, 光 OPEN的時間秒差有多少?
brook
資深會員


發表:57
回覆:323
積分:371
註冊:2002-07-12

發送簡訊給我
#3 引用回覆 回覆 發表時間:2010-08-31 11:55:43 IP:60.251.xxx.xxx 訂閱
兩者不相上下,約2秒.
但用TADOQuery開則需1分多鐘.

===================引 用 P.D. 文 章===================
你有沒有仔細計算過, 使用 QUERY1.OPEN 與 TABLE1.OPEN 時, 光 OPEN的時間秒差有多少?
hagar
版主


發表:143
回覆:4056
積分:4445
註冊:2002-04-14

發送簡訊給我
#4 引用回覆 回覆 發表時間:2010-08-31 14:31:32 IP:210.242.xxx.xxx 未訂閱
小弟這邊測試 Delphi 5 + TDatabase/TQuery/TTable + ODBC 連 SQL 2000
但無論是 TQuery 或 Table 在下 Last 指令時都需要較長的時間

重點是為什麼一次要抓這麼多的資料到 local 端?

參考:
http://delphi.ktop.com.tw/board.php?cid=18&fid=1496&tid=90538
編輯記錄
hagar 重新編輯於 2010-08-31 14:36:32, 註解 無‧
bestlong
站務副站長


發表:126
回覆:734
積分:512
註冊:2002-10-19

發送簡訊給我
#5 引用回覆 回覆 發表時間:2010-09-02 08:29:17 IP:210.242.xxx.xxx 訂閱
這是元件的工作特性所致
簡單的說
TTable.Open 拿到足夠的資料就顯示給你看
TQuery.Open 拿完全部的資料才顯示給你看
舊版 Delphi IDE 的功能表有 Database > SQL Monitor 工具可以觀察 TTable 與 TQuery 元件所執行的 SQL 命令
新版的 IDE 我就不知道此工具是否還存在
欲知詳情可以參閱 [精通 Delphi 4.x 實戰篇 作者李維] 一書有深入的分析
可以去興德資訊的網站去下載電子書


------
http://blog.bestlong.idv.tw/
http://www.bestlong.idv.tw/
http://delphi-ktop.bestlong.idv.tw/
brook
資深會員


發表:57
回覆:323
積分:371
註冊:2002-07-12

發送簡訊給我
#6 引用回覆 回覆 發表時間:2010-09-08 07:48:44 IP:60.251.xxx.xxx 訂閱
非常感謝各位大大努力提供的意見,這或許就是TQuery的特性,因為從bcb4到bcb2010一點也沒有改進.

想再請教hagar版主,你說"重點是為什麼一次要抓這麼多的資料到 local 端?"
那假如我想抓最後的100資料,我該如何下SQL指令,我用的資料庫沒有Top 100 也沒有limit 0,100.
我想過用SELECT id FROM KmOrders再去找最後100筆的資料的id,
再去select * from kmOrders Where Id > a AND id <= b
但我發現,用SELECT id FROM KmOrders,和用select * from kmOrders都是要花6秒,
所以加起來至少要12秒,這又讓我怯步,你們都是如何處理的呢?
bestlong
站務副站長


發表:126
回覆:734
積分:512
註冊:2002-10-19

發送簡訊給我
#7 引用回覆 回覆 發表時間:2010-09-08 08:55:04 IP:210.242.xxx.xxx 訂閱
撈最後 100 筆,可以先進行反向排序取 top 100 資料後再正向排序一次

以 MSSQL 環境來說簡單範例如下

[code sql]
select Part_num
from (select top 100 Part_num from PARTS order by Part_num desc) as T
order by Part_num asc
[/code]
------
http://blog.bestlong.idv.tw/
http://www.bestlong.idv.tw/
http://delphi-ktop.bestlong.idv.tw/
編輯記錄
bestlong 重新編輯於 2010-09-08 08:56:46, 註解 無‧
bestlong 重新編輯於 2010-09-08 08:58:17, 註解 無‧
hagar
版主


發表:143
回覆:4056
積分:4445
註冊:2002-04-14

發送簡訊給我
#8 引用回覆 回覆 發表時間:2010-09-08 10:53:15 IP:61.218.xxx.xxx 未訂閱
1.這種特性不是很好嗎?很快地抓到足夠顯示的資料, 等有需要時再去抓其它的資料, 這就可以節省抓資料的時間

2.KmOrders 的 id 欄位是流水號嗎?是的話, 下 SQL 時 Order By id Desc 即可(如果不堅持要抓100筆的話).

3.如果可以用 TADODataset / TADOQuery 的話, 這兩個元件有 MaxRecords 屬性可利用
brook
資深會員


發表:57
回覆:323
積分:371
註冊:2002-07-12

發送簡訊給我
#9 引用回覆 回覆 發表時間:2010-09-08 12:12:33 IP:60.251.xxx.xxx 訂閱
可是我用的DBMaker沒有top指令也沒有limit指令,才傷腦筋?



===================引 用 bestlong 文 章===================
撈最後 100 筆,可以先進行反向排序取 top 100 資料後再正向排序一次

以 MSSQL 環境來說簡單範例如下

[code sql]
select Part_num
from (select top 100 Part_num from PARTS order by Part_num desc) as T
order by Part_num asc
[/code]
brook
資深會員


發表:57
回覆:323
積分:371
註冊:2002-07-12

發送簡訊給我
#10 引用回覆 回覆 發表時間:2010-09-08 12:31:25 IP:60.251.xxx.xxx 訂閱

===================引 用 hagar 文 章===================
1.這種特性不是很好嗎?很快地抓到足夠顯示的資料, 等有需要時再去抓其它的資料, 這就可以節省抓資料的時間
2.KmOrders 的 id 欄位是流水號嗎?是的話, 下 SQL 時 Order By id Desc 即可(如果不堅持要抓100筆的話).
3.如果可以用 TADODataset / TADOQuery 的話, 這兩個元件有 MaxRecords 屬性可利用

1.其實我用Query1->Last();也不希望它把所有的資料都抓回來,一般拉一個TDBGrid不是都會拉一個TDBNavigator,
不小心按到TDBNavigator的末筆按鈕就掛一分鐘,或者自己設的按鈕下一筆,末筆吧!
還有直接拉TDBGrid的ScrollBar也會掛一分鐘.

2.至於反向排序也會遇到同樣的問題.

3.用TADOQuery則是open就先掛一分鐘.
herbert2
尊榮會員


發表:58
回覆:640
積分:894
註冊:2004-04-16

發送簡訊給我
#11 引用回覆 回覆 發表時間:2010-09-09 01:44:48 IP:202.39.xxx.xxx 訂閱
小弟通常用 Query1 (SELECT PrimaryKeyList FROM Table WHERE ... ORDER BY ...)
與 Query2 (SELECT * FROM Table WHERE PrimaryKey_1 = : Key_1 AND .....PrimaryKey_n = : Key_n)
做成 Master 與永遠只帶有一筆的 Detail.
如此 Query1 所需記憶體變少, Query2 只選一筆也很快.

謹供參考!
編輯記錄
herbert2 重新編輯於 2010-09-09 01:45:29, 註解 無‧
sryang
尊榮會員


發表:39
回覆:762
積分:920
註冊:2002-06-27

發送簡訊給我
#12 引用回覆 回覆 發表時間:2010-09-23 15:31:27 IP:111.254.xxx.xxx 訂閱
好樣的!
自己搞 client 端的 keyset cursor

===================引 用 herbert2 文 章===================
小弟通常用 Query1 (SELECT PrimaryKeyList FROM Table WHERE ... ORDER BY ...)
與 Query2 (SELECT * FROM Table WHERE PrimaryKey_1 = : Key_1 AND .....PrimaryKey_n = : Key_n)
做成 Master 與永遠只帶有一筆的 Detail.
如此 Query1 所需記憶體變少, Query2 只選一筆也很快.

謹供參考!
------
歡迎參訪 "腦殘賤貓的備忘錄" http://maolaoda.blogspot.com/
aven.ko
一般會員


發表:0
回覆:1
積分:5
註冊:2008-08-25

發送簡訊給我
#13 引用回覆 回覆 發表時間:2010-09-29 10:21:59 IP:61.220.xxx.xxx 訂閱
我個人也有遇過類似的經驗, 我的解決方式如下, 因情況可能不同, 所以僅供參考!

此為你的SQL Statement:
SELECT * FROM KmOrders

請試著改為:

SELECT COLUMN1, COLUMN2, COLUMN3 FROM KmOrders


===================引 用 brook 文 章===================
請教各位大大:
1.我用WINXP,Delphi2010,DBMaker3.7.
2.資料筆數約2萬筆.
3.我拉一個TDataBase,TQuery,TDataSource,TDBGrid,及兩個TButton.
4.當我按Button1,執行約2秒,再按Button2時卻要60幾秒.
5.TQuery改成TTable,按Button2只花不到1秒,兩者速度為何差如此大呢?.
6.請教各位大大,我該往哪方面測呢?我測過BCB4,BCB5,BCB6,BCB2010也是同樣結果?


[code delphi]
請在此區域輸入程式碼
procedure TForm1.Button1Click(Sender: TObject);
begin
Query1.SQL.Clear();
Query1.SQL.Add('SELECT * FROM KmOrders');
Query1.Close();
Query1.Open();
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
Query1.Last();
end;
[/code]

TWY
高階會員


發表:2
回覆:133
積分:152
註冊:2009-09-02

發送簡訊給我
#14 引用回覆 回覆 發表時間:2010-09-29 11:04:41 IP:59.120.xxx.xxx 訂閱
在沒有 top 或 limit 指令可用時,可利用 self-join 技巧選出第 N 筆或某資料區間。
以下是個範例,沒有考慮到效能及防呆請自行修改;若需兩個欄位合在一起才是PK只要把兩個欄位合併亦可 (ex: AAA||BBB)。

--利用 Self-Join 技巧選出最後 10 筆資料 (Oracle 為例)
select D.* from (
select A.strUserCode,count(*) as MySortNo
from UserCode A,UserCode B
where A.strUserCode>=B.strUserCode
group by A.strUserCode
order by MySortNo
) C,UserCode D
where C.MySortNo > (select count(*)-10 from UserCode)
and C.strUserCode=D.strUserCode
系統時間:2024-04-25 21:09:31
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!