做一個簡單的QueryService,在跟蹤過程中發現,用戶端一個查詢,會被觸發兩次。怎麼會這樣,這嚴重影響伺服器性能。
用戶端的代碼非常簡單,就是執行一個SQL,通過QueryService傳回結果:
kbmMWClientQuery2.Close;
kbmMWClientQuery2.Open;
于是利用伺服器端的QueryService的事件OnQueryStatement進一步檢查SQL的執行情況,把SQL寫到Memo中:
procedure
TkbmMWQueryService3.kbmMWQueryServiceQueryStatement(Sender:
TObject;
Place: TkbmMWQueryOperationType; var
NamedQueryName, Statement: string);
begin
Form1.Memo1.Lines.Add(Format('Named Query:%s |
Statement:%s',[NamedQueryName,Statement]));
end;

用dbMonitor檢查也是重複的:

發生這個問題,是因為在伺服器端的Query,需要先從資料庫中查詢出表的結構及查詢使用的參數,然後再查詢資料記錄。
解決該問題的方法:
1:利用Cache制,對Metadata進行緩存,用以取代每次查詢都要從資料庫中先查詢出結構;在伺服器端及用戶端都可以利用Cache.
kbmMWClientQuery2.Cached:=True;
kbmMWClientQuery2.CacheFlags:=[mwcfDontAge,mwcfDontGarbageCollect,mwcfDefsOnly];
2:設定Query的AutoFieldOnOpen:=mwafoWithData;
關于如果使用kbmMW的Cache,參見昨天寫的内容。