基於中間件的查詢優化模型
傳統的客戶/服務器模式是一種雙層的結構,通常是一台個人計算機做客戶機使用(運行客戶端程序),另外一台服務器用於存放後台的數據庫系統,應用程序可客戶端直接相連,中間沒有其他的邏輯。在MIS系統的軟件開發過程中,查詢數據是必不可少的一個重要部分,而如何幫助用戶在數據庫中進行快速而有效的查詢數據是軟件開發人員十分關心的事情。我從我做過的2個MIS系統中關於數據查詢方面,大致總結出以下幾種方法:
1.
固定結構方式:即程序員根據客戶的業務要求定制客戶端查詢程序,這種定制的程序沒有通用性。或者業務邏輯也存在於後台數據庫中,以觸發器(trigger)的方式實現。這種方式有一個很大的缺點,就是一旦客戶的業務邏輯有所改變的話,將引起應用程序的修改以及後台觸發器的修改,將所有程序模塊都重新修改、編譯、連接的工作量是相當大的。另外由於這種結構將用戶界面和業務邏輯以及數據源綁定在一起,會消耗客戶機的大量資源,對客戶機來說是一個很大的負擔。
2.
靈活結構方式:既除了使用固定查詢命令以外,再做一些讓系統管理人員可以修改查詢命令的界面。也就是讓系統管理人員可以編寫
SQL語句的方式,這種方式雖然可以提高查詢質量,但對與非專業的操作人員來講,是很困難的。
3. 基於中間件的數據查詢優化模型:本文就以中間件和分布式系統為理論基礎,以曾經開發過的成都市康泰電器MIS系統為例介紹這種數據查詢模型,相信它給用戶提供了更方便和更快速的服務。
1. 什麼是中間件:
為解決分布異構問題,人們提出了中間件(middleware)的概念。中間件是位於平台(硬件和操作系統)和應用之間的通用服務,如圖3所示,這些服務具有標准的程序接口和協議。針對不同的操作系統和硬件平台,它們可以有符合接口和協議規范的多種實現。也許很難給中間件一個嚴格的定義,想了解的讀者可以去http://www.huihoo.com/middleware/了解相關資料。
2. 開發人員在做查詢模塊的時候應該注意的問題:
一般來說,客戶只關心他們所需要的數據和怎樣查詢出這些數據,而對與這條查詢語句是和生成的,就不會關心了。舉一個例子,一個庫房管理系統,包括入庫情況,出庫情況和結存情況等等。客戶只關心如何得到一個產品的出庫數量,入庫數量和當前的結存數量。而對於這個庫房管理系統是如何生成,和查詢語句的SQL代碼和數據表,一律不感興趣。以康泰電器MIS系統為例,它采用的是clIEnt/server結構,根據我對MIS系統的了解,只要應用系統的客戶端數目在200個用戶以內而且是在同一個局域網內,那麼client/server結構在執行MIS系統就足夠了。但是,眾所周知clIEnt/server結構存在很多問題。既前面
固定結構方式中所談到的一些問題,導致它影響了數據庫的執行效率。
加上近年來INTERNET/INTRANET應用的興起,對於企業的運作方式有了重大的影響,康泰電器的企業主管要求開發產品查詢的信息給所有在INTERNET/INTRANET上的潛在用戶,所以MIS系統必須能夠讓客戶使用浏覽器來查詢所有的產品信息,事實上系統結構已經進入了分布式的結構了。因為它多了一台WEB 服務器。以前的系統要提供INTERNET/INTRANET的存取形式時,舊的MIS系統必然以新的技術編寫一次。這必然加大了開發人員的工作,也提高了成本。所以我想,只是由於多了BS的查詢方式,為什麼不利用現在流行的中間件的思想開發一個新的查詢模型呢?
3.查詢系統的模型:
我通過分析一些查詢的語句,了解到了他們的一些共同性,並且共同性比較
突出,因為他們不是離散出現的。比如所有關於庫房查詢的語句構成了庫房管理查詢系統,所有財務收支的查詢語句構成了收支查詢系統,我將查詢的語句進行分類處理,structN_class={Table1,Table2…..Tablen};Datawarehouse={ struct 1_class, struct 2_class……structN_class}.而我就是要在structN_class上使用微軟的DCOM 技術創建我們的查詢系統。
它的主要技術特征是把查詢語句和系統的界面完全分開,不是原來的client/server結構了,我把client分為2個部分,client和SelectCom-Server.。不管用戶是在clIEnt端,還是在采用浏覽器界面。把用戶輸入的查詢條件和類別先提交到SelectCom-Server. SelectCom-Server.根據用戶輸入的查詢條件和類別自動生成查詢語句。然後把它們提交給數據庫,最後數據庫運行查詢語句,再將查詢 的數據交給SelectCom-Server. SelectCom-Server.在把數據返回給clIEnt端,這樣就完成了查詢工作。
我認為它的好處有以下幾點:
由於SelectCom-Server.和clIEnt是分離的,那麼一個用戶使用過的查詢條件可以被其它用戶使用共享。這樣使網絡和數據庫的開銷大大降低了。還可以根據已經使用過的查詢條件來縮小查詢的范圍。在由於我已經把深一級的權限加在了SelectCom-Server.上,它就可以拒絕一些核心數據的查詢,提高了數據的安全性
也減輕了代碼的從用性,因為這種分布式的系統,考慮安全性按照常規不僅要完善clIEnt/server結構,而且要完善BS結構。再者,它還有利與系統管理人員的維護,他要排錯就只需要對SelectCom-Server.上的查詢語句進行分析。
4實現:
限與篇幅的問題,我不會把DCOM實現的代碼寫出來,因為這種分布式系統接口編程牽涉到的東西太多了,只是談一下查詢語句的構成原理和它的優化,這才是最主要的。
但是這其中牽涉的東西也很多,比如:合理使用索引,避免或簡化排序,消除對大型表行數據的順序存取,避免相關子查詢,用排序來取代非順序存取等等。
先說構成的原理,查詢subsentence的生成依據是各個字段屬於哪個關系表而產生的,當同一個字段屬於2個關系表共同擁有的時候,那麼它就是連接的字段。
例如有3個關系表:
table1(Rnumber,Name,Guige),table2(Cnumber,Xinghao,Guige),table3(Score,Guige)
那麼可以生成一個查詢subsentence的成員N=table1.Guige= table2.Guige.
而對於如何實現一個用戶使用過的查詢條件可以被其它用戶使用共享如下所敘述:關鍵是建立臨時文件,(我把其優化方式也加在其中)。以曾經開發過的成都市康泰電器MIS系統為例,把表的一個子集進行排序並創建臨時表,有時能加速查詢。它有助於避免多重排序操作,而且在其他方面還能簡化優化器的工作。例如:
SELECT cust.name,rcvbles.balance,……other columns
FROM cust,rcvbles
WHERE cust.customer_id = rcvlbes.customer_id
AND rcvblls.balance>0
AND cust.postcode>“98000”
ORDER BY cust.name
如果這個查詢要被執行多次而不止一次,可以把所有未付款的客戶找出來放在一個臨時文件中,並按客戶的名字進行排序:
SELECT cust.name,rcvbles.balance,……other columns
FROM cust,rcvbles
WHERE cust.customer_id = rcvlbes.customer_id
AND rcvblls.balance>0
ORDER BY cust.name
INTO TEMP cust_with_balance
然後以下面的方式在臨時表中查詢:
SELECT * FROM cust_with_balance
WHERE postcode>“98000”
臨時表中的行要比主表中的行少,而且物理順序就是所要求的順序,減少了磁盤I/O,所以查詢工作量可以得到大幅減少。為了加速查詢語句的生成和搜索我們使用的臨時緩存表。進行搜索時,首先搜索臨時緩存表,再搜索語句生成表。
但是要注意的是臨時表創建後不會反映主表的修改。在主表中數據頻繁修改的情況下,注意不要丟失數據。但是我到現在還沒有完全的解決這個問題,有興趣的讀者可以想想。
5.查詢語句的存儲結構:
一個查詢語句可以分解成一個或許多的查詢subsentence,一個查詢subsentence還可以分解成多個更小的查詢subsentence。實際上他們是一個樹型結構,所以每一個新的查詢語句就是新的父節點。我們的臨時緩存表就是已這種結構進行存儲的。
6.結束語
此模型在實際的運用中運行良好,而且對於用戶來說簡單實用,基本滿足了用戶的分布式系統的要求。盡管用戶對查詢的要求不一致,但是利用基於中間件的查詢優化模型具有友好的人機交互界面,查詢條件能夠自動靈活的生成,增加了實用性。對於開發人員來說減少了工作量,在提高了數據的安全性的同時也減輕了代碼的二次開發等等。