提公升資料庫查詢的效能

2021-08-25 20:00:35 字數 4091 閱讀 8298

資料庫查詢效能的提公升也是涉及到開發中的各個階段,在開發中選用正確的查詢方法無疑是最基礎也最簡單的。

1 、sql語句的優化

使用正確的sql語句可以在很大程度上提高系統的查詢效能。獲得同樣資料而採用不同方式的sql語句在效能上的差距可能是十分巨大的。

由於hibernate是對jdbc的封裝,sql語句的產生都是動態由hibernate自動完成的。hibernate產生sql語句的方式有兩種:一種是通過開發人員編寫的hql語句來生成,另一種是依據開發人員對關聯物件的訪問來自動生成相應的sql語句。

至於使用什麼樣的sql語句可以獲得更好的效能要依據資料庫的結構以及所要獲取資料的具體情況來進行處理。在確定了所要執行的sql語句後,可以通過以下三個方面來影響hibernate所生成的sql語句:

◆hql語句的書寫方法。

◆查詢時所使用的查詢方法。

◆物件關聯時所使用的抓取策略。

2 、使用正確的查詢方法

在前面已經介紹過,執行資料查詢功能的基本方法有兩種:一種是得到單個持久化物件的get()方法和load()方法,另一種是query物件的list()方法和iterator()方法。在開發中應該依據不同的情況選用正確的方法。

get()方法和load()方法的區別在於對二級快取的使用上。load()方法會使用二級快取,而get()方法在一級快取沒有找到的情況下會直接查詢資料庫,不會去二級快取中查詢。在使用中,對使用了二級快取的物件進行查詢時最好使用load()方法,以充分利用二級快取來提高檢索的效率。

list()方法和iterator()方法之間的區別可以從以下幾個方面來進行比較。

◆執行的查詢不同

list()方法在執行時,是直接執行查詢結果所需要的查詢語句,而iterator()方法則是先執行得到物件id的查詢,然後再根據每個id值去取得所要查詢的物件。因此,對於list()方式的查詢通常只會執行乙個sql語句,而對於iterator()方法的查詢則可能需要執行n+1條sql語句(n為結果集中的記錄數)。

iterator()方法只是可能執行n+1條資料,具體執行sql語句的數量取決於快取的情況以及對結果集的訪問情況。

◆快取的使用

list()方法只能使用二級快取中的查詢快取,而無法使用二級快取對單個物件的快取(但是會把查詢出的物件放入二級快取中)。所以,除非重複執行相同的查詢操作,否則無法利用快取的機制來提高查詢的效率。

iterator()方法則可以充分利用二級快取,在根據id檢索物件的時候會首先到快取中查詢,只有在找不到的情況下才會執行相應的查詢語句。所以,快取中物件的存在與否會影響到sql語句的執行數量。

◆對於結果集的處理方法不同

list()方法會一次獲得所有的結果集物件,而且它會依據查詢的結果初始化所有的結果集物件。這在結果集非常大的時候必然會佔據非常多的記憶體,甚至會造成記憶體溢位情況的發生。

iterator()方法在執行時不會一次初始化所有的物件,而是根據對結果集的訪問情況來初始化物件。因此在訪問中可以控制快取中物件的數量,以避免占用過多快取,導致記憶體溢位情況的發生。使用iterator()方法的另外乙個好處是,如果只需要結果集中的部分記錄,那麼沒有被用到的結果物件根本不會被初始化。所以,對結果集的訪問情況也是呼叫iterator()方法時執行資料庫sql語句多少的乙個因素。

所以,在使用query物件執行資料查詢時應該從以上幾個方面去考慮使用何種方法來執行資料庫的查詢操作。

hibernate優化方法四:使用正確的抓取策略

所謂抓取策略(fetching strategy)是指當應用程式需要利用關聯關係進行物件獲取的時候,hibernate獲取關聯物件的策略。抓取策略可以在o/r對映的元資料中宣告,也可以在特定的hql或條件查詢中宣告。

hibernate 3定義了以下幾種抓取策略。

連線抓取(join fetching)

連線抓取是指hibernate在獲得關聯物件時會在select語句中使用外連線的方式來獲得關聯物件。

查詢抓取(select fetching)

查詢抓取是指hibernate通過另外一條select語句來抓取當前物件的關聯物件的方式。這也是通過外來鍵的方式來執行資料庫的查詢。與連線抓取的區別在於,通常情況下這個select語句不是立即執行的,而是在訪問到關聯物件的時候才會執行。

子查詢抓取(subselect fetching)

子查詢抓取也是指hibernate通過另外一條select語句來抓取當前物件的關聯物件的方式。與查詢抓取的區別在於它所採用的select語句的方式為子查詢,而不是通過外連線。

批量抓取(batch fetching)

批量抓取是對查詢抓取的優化,它會依據主鍵或者外來鍵的列表來通過單條select語句實現管理物件的批量抓取。

以上介紹的是hibernate 3所提供的抓取策略,也就是抓取關聯物件的手段。為了提公升系統的效能,在抓取關聯物件的時機上,還有以下一些選擇。

立即抓取(immediate fetching)

立即抓取是指宿主物件被載入時,它所關聯的物件也會被立即載入。

延遲集合抓取(lazy collection fetching)

延遲集合抓取是指在載入宿主物件時,並不立即載入它所關聯的物件,而是到應用程式訪問關聯物件的時候才抓取關聯物件。這是集合關聯物件的預設行為。

延遲**抓取(lazy proxy fetching)

延遲**抓取是指在返回單值關聯物件的情況下,並不在對其進行get操作時抓取,而是直到呼叫其某個方法的時候才會抓取這個物件。

延遲屬性載入(lazy attribute fetching)

延遲屬性載入是指在關聯物件被訪問的時候才進行關聯物件的抓取。

介紹了hibernate所提供的關聯物件的抓取方法和抓取時機,這兩個方面的因素都會影響hibernate的抓取行為,最重要的是要清楚這兩方面的影響是不同的,不要將這兩個因素混淆,在開發中要結合實際情況選用正確的抓取策略和合適的抓取時機。

◆抓取時機的選擇

在hibernate 3中,對於集合型別的關聯在預設情況下會使用延遲集合載入的抓取時機,而對於返回單值型別的關聯在預設情況下會使用延遲**抓取的抓取時機。

對於立即抓取在開發中很少被用到,因為這很可能會造成不必要的資料庫操作,從而影響系統的效能。當宿主物件和關聯物件總是被同時訪問的時候才有可能會用到這種抓取時機。另外,使用立即連線抓取可以通過外連線來減少查詢sql語句的數量,所以,也會在某些特殊的情況下使用。

然而,延遲載入又會面臨另外乙個問題,如果在session關閉前關聯物件沒有被例項化,那麼在訪問關聯物件的時候就會丟擲異常。處理的方法就是在事務提交之前就完成對關聯物件的訪問。

所以,在通常情況下都會使用延遲的方式來抓取關聯的物件。因為每個立即抓取都會導致關聯物件的立即例項化,太多的立即抓取關聯會導致大量的物件被例項化,從而占用過多的記憶體資源。

◆抓取策略的選取

對於抓取策略的選取將影響到抓取關聯物件的方式,也就是抓取關聯物件時所執行的sql語句。這就要根據實際的業務需求、資料的數量以及資料庫的結構來進行選擇了。

在這裡需要注意的是,通常情況下都會在執行查詢的時候針對每個查詢來指定對其合適的抓取策略。指定抓取策略的方法如下所示:

user user = (user) session.createcriteria(user.class)

.setfetchmode("permissions", fetchmode.join)

.add( restrictions.ideq(userid) )

.uniqueresult();

hibernate優化方法五:查詢效能提公升小結

在本小節中介紹了查詢效能提公升的方法,關鍵是如何通過優化sql語句來提公升系統的查詢效能。查詢方法和抓取策略的影響也是通過執行查詢方式和sql語句的多少來改變系統的效能的。這些都屬於開發人員所應該掌握的基本技能,避免由於開發不當而導致系統效能的低下。

在效能調整中,除了前面介紹的執行sql語句的因素外,對於快取的使用也會影響系統的效能。通常來說,快取的使用會增加系統查詢的效能,而降低系統增加、修改和刪除操作的效能(因為要進行快取的同步處理)。所以,開發人員應該能夠正確地使用有效的快取來提高資料查詢的效能,而要避免濫用快取而導致的系統效能變低。在採用快取的時候也應該注意調整自己的檢索策略和查詢方法,這三者配合起來才可以達到最優的效能。

另外,事務的使用策略也會影響到系統的效能。選取正確的事務隔離級別以及使用。

提公升資料庫查詢的效能

資料庫查詢效能的提公升也是涉及到開發中的各個階段,在開發中選用正確的查詢方法無疑是最基礎也最簡單的。14.3.3.1 sql語句的優化 使用正確的sql語句可以在很大程度上提高系統的查詢效能。獲得同樣資料而採用不同方式的sql語句在效能上的差距可能是十分巨大的。由於hibernate是對jdbc的封...

資料庫索引效能提公升

乙個索引是儲存的表中乙個特定列的值資料結構 最常見的是b tree 索引是在表的列上建立。所以,要記住的關鍵點是索引包含乙個表中列的值,並且這些值儲存在乙個資料結構中。請記住記住這一點 索引是一種資料結構 b tree 是最常用的用於索引的資料結構。因為它們是時間複雜度低,查詢 刪除 插入操作都可以...

資料庫查詢提公升查詢效率

在乙個千萬級別的資料庫查詢中,提公升查詢效率方法 對查詢優化,要盡量避免全表掃瞄,首先考慮在where和orderby涉及的列上建索引 應盡量避免在where字句中對null值進行判斷,否則導致引擎放棄索引而進行全表掃瞄,如 select id from t where num is null,可以...