<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 495,  comments - 11,  trackbacks - 0

    ?????? 數(shù)據(jù)庫查詢性能的提升也是涉及到開發(fā)中的各個(gè)階段,在開發(fā)中選用正確的查詢方法無疑是最基礎(chǔ)也最簡單的。

    SQL語句的優(yōu)化

    ?????? 使用正確的SQL語句可以在很大程度上提高系統(tǒng)的查詢性能。獲得同樣數(shù)據(jù)而采用不同方式的SQL語句在性能上的差距可能是十分巨大的。

    ?????? 由于Hibernate是對(duì)JDBC的封裝,SQL語句的產(chǎn)生都是動(dòng)態(tài)由Hibernate自動(dòng)完成的。Hibernate產(chǎn)生SQL語句的方式有兩種:一種是通過開發(fā)人員編寫的HQL語句來生成,另一種是依據(jù)開發(fā)人員對(duì)關(guān)聯(lián)對(duì)象的訪問來自動(dòng)生成相應(yīng)的SQL語句。

    ?????? 至于使用什么樣的SQL語句可以獲得更好的性能要依據(jù)數(shù)據(jù)庫的結(jié)構(gòu)以及所要獲取數(shù)據(jù)的具體情況來進(jìn)行處理。在確定了所要執(zhí)行的SQL語句后,可以通過以下三個(gè)方面來影響Hibernate所生成的SQL語句:

    ●?? HQL語句的書寫方法。

    ●?? 查詢時(shí)所使用的查詢方法。

    ●?? 對(duì)象關(guān)聯(lián)時(shí)所使用的抓取策略。

    使用正確的查詢方法

    ?????? 在前面已經(jīng)介紹過,執(zhí)行數(shù)據(jù)查詢功能的基本方法有兩種:一種是得到單個(gè)持久化對(duì)象的get()方法和load()方法,另一種是Query對(duì)象的list()方法和iterator()方法。在開發(fā)中應(yīng)該依據(jù)不同的情況選用正確的方法。

    ?????? get()方法和load()方法的區(qū)別在于對(duì)二級(jí)緩存的使用上。load()方法會(huì)使用二級(jí)緩存,而get()方法在一級(jí)緩存沒有找到的情況下會(huì)直接查詢數(shù)據(jù)庫,不會(huì)去二級(jí)緩存中查找。在使用中,對(duì)使用了二級(jí)緩存的對(duì)象進(jìn)行查詢時(shí)最好使用load()方法,以充分利用二級(jí)緩存來提高檢索的效率。

    ?????? list()方法和iterator()方法之間的區(qū)別可以從以下幾個(gè)方面來進(jìn)行比較。

    ●?? 執(zhí)行的查詢不同

    ?????? list()方法在執(zhí)行時(shí),是直接運(yùn)行查詢結(jié)果所需要的查詢語句,而iterator()方法則是先執(zhí)行得到對(duì)象ID的查詢,然后再根據(jù)每個(gè)ID值去取得所要查詢的對(duì)象。因此,對(duì)于list()方式的查詢通常只會(huì)執(zhí)行一個(gè)SQL語句,而對(duì)于iterator()方法的查詢則可能需要執(zhí)行N+1條SQL語句(N為結(jié)果集中的記錄數(shù))。

    ?????? iterator()方法只是可能執(zhí)行N+1條數(shù)據(jù),具體執(zhí)行SQL語句的數(shù)量取決于緩存的情況以及對(duì)結(jié)果集的訪問情況。

    ●?? 緩存的使用

    ?????? list()方法只能使用二級(jí)緩存中的查詢緩存,而無法使用二級(jí)緩存對(duì)單個(gè)對(duì)象的緩存(但是會(huì)把查詢出的對(duì)象放入二級(jí)緩存中)。所以,除非重復(fù)執(zhí)行相同的查詢操作,否則無法利用緩存的機(jī)制來提高查詢的效率。

    ?????? iterator()方法則可以充分利用二級(jí)緩存,在根據(jù)ID檢索對(duì)象的時(shí)候會(huì)首先到緩存中查找,只有在找不到的情況下才會(huì)執(zhí)行相應(yīng)的查詢語句。所以,緩存中對(duì)象的存在與否會(huì)影響到SQL語句的執(zhí)行數(shù)量。

    ●?? 對(duì)于結(jié)果集的處理方法不同

    ?????? list()方法會(huì)一次獲得所有的結(jié)果集對(duì)象,而且它會(huì)依據(jù)查詢的結(jié)果初始化所有的結(jié)果集對(duì)象。這在結(jié)果集非常大的時(shí)候必然會(huì)占據(jù)非常多的內(nèi)存,甚至?xí)斐蓛?nèi)存溢出情況的發(fā)生。

    ?????? iterator()方法在執(zhí)行時(shí)不會(huì)一次初始化所有的對(duì)象,而是根據(jù)對(duì)結(jié)果集的訪問情況來初始化對(duì)象。因此在訪問中可以控制緩存中對(duì)象的數(shù)量,以避免占用過多緩存,導(dǎo)致內(nèi)存溢出情況的發(fā)生。使用iterator()方法的另外一個(gè)好處是,如果只需要結(jié)果集中的部分記錄,那么沒有被用到的結(jié)果對(duì)象根本不會(huì)被初始化。所以,對(duì)結(jié)果集的訪問情況也是調(diào)用iterator()方法時(shí)執(zhí)行數(shù)據(jù)庫SQL語句多少的一個(gè)因素。

    ?????? 所以,在使用Query對(duì)象執(zhí)行數(shù)據(jù)查詢時(shí)應(yīng)該從以上幾個(gè)方面去考慮使用何種方法來執(zhí)行數(shù)據(jù)庫的查詢操作。

    使用正確的抓取策略

    ?????? 所謂抓取策略(fetching strategy)是指當(dāng)應(yīng)用程序需要利用關(guān)聯(lián)關(guān)系進(jìn)行對(duì)象獲取的時(shí)候,Hibernate獲取關(guān)聯(lián)對(duì)象的策略。抓取策略可以在O/R映射的元數(shù)據(jù)中聲明,也可以在特定的HQL或條件查詢中聲明。

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

    ●?? 連接抓取(Join fetching)

    ?????? 連接抓取是指Hibernate在獲得關(guān)聯(lián)對(duì)象時(shí)會(huì)在SELECT語句中使用外連接的方式來獲得關(guān)聯(lián)對(duì)象。

    ●?? 查詢抓取(Select fetching)

    ?????? 查詢抓取是指Hibernate通過另外一條SELECT語句來抓取當(dāng)前對(duì)象的關(guān)聯(lián)對(duì)象的方式。這也是通過外鍵的方式來執(zhí)行數(shù)據(jù)庫的查詢。與連接抓取的區(qū)別在于,通常情況下這個(gè)SELECT語句不是立即執(zhí)行的,而是在訪問到關(guān)聯(lián)對(duì)象的時(shí)候才會(huì)執(zhí)行。

    ●?? 子查詢抓取(Subselect fetching)

    ?????? 子查詢抓取也是指Hibernate通過另外一條SELECT語句來抓取當(dāng)前對(duì)象的關(guān)聯(lián)對(duì)象的方式。與查詢抓取的區(qū)別在于它所采用的SELECT語句的方式為子查詢,而不是通過外連接。

    ●?? 批量抓取(Batch fetching)

    ?????? 批量抓取是對(duì)查詢抓取的優(yōu)化,它會(huì)依據(jù)主鍵或者外鍵的列表來通過單條SELECT語句實(shí)現(xiàn)管理對(duì)象的批量抓取。

    以上介紹的是Hibernate 3所提供的抓取策略,也就是抓取關(guān)聯(lián)對(duì)象的手段。為了提升系統(tǒng)的性能,在抓取關(guān)聯(lián)對(duì)象的時(shí)機(jī)上,還有以下一些選擇。

    ●?? 立即抓取(Immediate fetching)

    ?????? 立即抓取是指宿主對(duì)象被加載時(shí),它所關(guān)聯(lián)的對(duì)象也會(huì)被立即加載。

    ●?? 延遲集合抓取(Lazy collection fetching)

    ?????? 延遲集合抓取是指在加載宿主對(duì)象時(shí),并不立即加載它所關(guān)聯(lián)的對(duì)象,而是到應(yīng)用程序訪問關(guān)聯(lián)對(duì)象的時(shí)候才抓取關(guān)聯(lián)對(duì)象。這是集合關(guān)聯(lián)對(duì)象的默認(rèn)行為。

    ●?? 延遲代理抓取(Lazy proxy fetching)

    ?????? 延遲代理抓取是指在返回單值關(guān)聯(lián)對(duì)象的情況下,并不在對(duì)其進(jìn)行g(shù)et操作時(shí)抓取,而是直到調(diào)用其某個(gè)方法的時(shí)候才會(huì)抓取這個(gè)對(duì)象。

    ●?? 延遲屬性加載(Lazy attribute fetching)

    ?????? 延遲屬性加載是指在關(guān)聯(lián)對(duì)象被訪問的時(shí)候才進(jìn)行關(guān)聯(lián)對(duì)象的抓取。

    ?????? 介紹了Hibernate所提供的關(guān)聯(lián)對(duì)象的抓取方法和抓取時(shí)機(jī),這兩個(gè)方面的因素都會(huì)影響Hibernate的抓取行為,最重要的是要清楚這兩方面的影響是不同的,不要將這兩個(gè)因素混淆,在開發(fā)中要結(jié)合實(shí)際情況選用正確的抓取策略和合適的抓取時(shí)機(jī)。

    ?????? 抓取時(shí)機(jī)的選擇

    ?????? 在Hibernate 3中,對(duì)于集合類型的關(guān)聯(lián)在默認(rèn)情況下會(huì)使用延遲集合加載的抓取時(shí)機(jī),而對(duì)于返回單值類型的關(guān)聯(lián)在默認(rèn)情況下會(huì)使用延遲代理抓取的抓取時(shí)機(jī)。

    ?????? 對(duì)于立即抓取在開發(fā)中很少被用到,因?yàn)檫@很可能會(huì)造成不必要的數(shù)據(jù)庫操作,從而影響系統(tǒng)的性能。當(dāng)宿主對(duì)象和關(guān)聯(lián)對(duì)象總是被同時(shí)訪問的時(shí)候才有可能會(huì)用到這種抓取時(shí)機(jī)。另外,使用立即連接抓取可以通過外連接來減少查詢SQL語句的數(shù)量,所以,也會(huì)在某些特殊的情況下使用。

    ?????? 然而,延遲加載又會(huì)面臨另外一個(gè)問題,如果在Session關(guān)閉前關(guān)聯(lián)對(duì)象沒有被實(shí)例化,那么在訪問關(guān)聯(lián)對(duì)象的時(shí)候就會(huì)拋出異常。處理的方法就是在事務(wù)提交之前就完成對(duì)關(guān)聯(lián)對(duì)象的訪問。

    ?????? 所以,在通常情況下都會(huì)使用延遲的方式來抓取關(guān)聯(lián)的對(duì)象。因?yàn)槊總€(gè)立即抓取都會(huì)導(dǎo)致關(guān)聯(lián)對(duì)象的立即實(shí)例化,太多的立即抓取關(guān)聯(lián)會(huì)導(dǎo)致大量的對(duì)象被實(shí)例化,從而占用過多的內(nèi)存資源。

    ?????? 抓取策略的選取

    ?????? 對(duì)于抓取策略的選取將影響到抓取關(guān)聯(lián)對(duì)象的方式,也就是抓取關(guān)聯(lián)對(duì)象時(shí)所執(zhí)行的SQL語句。這就要根據(jù)實(shí)際的業(yè)務(wù)需求、數(shù)據(jù)的數(shù)量以及數(shù)據(jù)庫的結(jié)構(gòu)來進(jìn)行選擇了。

    在這里需要注意的是,通常情況下都會(huì)在執(zhí)行查詢的時(shí)候針對(duì)每個(gè)查詢來指定對(duì)其合適的抓取策略。指定抓取策略的方法如下所示:

    ?????? User user = (User) session.createCriteria(User.class)

    ??????????? ?????? .setFetchMode("permissions", FetchMode.JOIN)

    ??????????? ?????? .add( Restrictions.idEq(userId) )

    ??????????? ?????? .uniqueResult();

    ?????? 本文介紹了查詢性能提升的方法,關(guān)鍵是如何通過優(yōu)化SQL語句來提升系統(tǒng)的查詢性能。查詢方法和抓取策略的影響也是通過執(zhí)行查詢方式和SQL語句的多少來改變系統(tǒng)的性能的。這些都屬于開發(fā)人員所應(yīng)該掌握的基本技能,避免由于開發(fā)不當(dāng)而導(dǎo)致系統(tǒng)性能的低下。

    ?????? 在性能調(diào)整中,除了前面介紹的執(zhí)行SQL語句的因素外,對(duì)于緩存的使用也會(huì)影響系統(tǒng)的性能。通常來說,緩存的使用會(huì)增加系統(tǒng)查詢的性能,而降低系統(tǒng)增加、修改和刪除操作的性能(因?yàn)橐M(jìn)行緩存的同步處理)。所以,開發(fā)人員應(yīng)該能夠正確地使用有效的緩存來提高數(shù)據(jù)查詢的性能,而要避免濫用緩存而導(dǎo)致的系統(tǒng)性能變低。在采用緩存的時(shí)候也應(yīng)該注意調(diào)整自己的檢索策略和查詢方法,這三者配合起來才可以達(dá)到最優(yōu)的性能。

    ?????? 另外,事務(wù)的使用策略也會(huì)影響到系統(tǒng)的性能。選取正確的事務(wù)隔離級(jí)別以及使用正確的鎖機(jī)制來控制數(shù)據(jù)的并發(fā)訪問都會(huì)影響到系統(tǒng)的性能。

    posted on 2009-07-19 21:36 jadmin 閱讀(82) 評(píng)論(0)  編輯  收藏

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 成年私人影院免费视频网站| 免费真实播放国产乱子伦| 亚洲天堂中文字幕在线| 亚洲av成人中文无码专区| 九九九精品成人免费视频| 33333在线亚洲| 夫妻免费无码V看片| 亚洲精品乱码久久久久久久久久久久| 午夜肉伦伦影院久久精品免费看国产一区二区三区 | 亚洲日本视频在线观看| 成人免费区一区二区三区 | 男男黄GAY片免费网站WWW| 91免费播放人人爽人人快乐| 亚洲免费无码在线| 亚洲人精品亚洲人成在线| 两性色午夜视频免费播放| 日韩免费视频播播| 亚洲免费二区三区| 成人免费看黄20分钟| 免费人成视频在线播放| 免费观看成人毛片a片2008| 亚洲人片在线观看天堂无码| 国产v片免费播放| 久久久久久噜噜精品免费直播| 在线观看91精品国产不卡免费| 免费看一级一级人妻片| 亚洲人色婷婷成人网站在线观看 | 亚洲AV综合色区无码一区爱AV| 色噜噜噜噜亚洲第一| 老司机亚洲精品影视www| 噜噜噜亚洲色成人网站| 亚洲人成在线播放网站| 亚欧人成精品免费观看| 美国免费高清一级毛片| 亚洲国产精品无码久久一区二区 | 69精品免费视频| 亚洲国产精品无码观看久久| 美女视频黄免费亚洲| 亚洲综合久久成人69| 日本特黄特色aa大片免费| 中文字幕av免费专区|