青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 297,  comments - 15,  trackbacks - 0
Dejan Bosanac是一個(gè)軟件開發(fā)者,技術(shù)顧問和作家。他關(guān)注不同技術(shù)的集成和互操作,尤其是與Java以及Web開發(fā)相關(guān)的領(lǐng)域。

數(shù)據(jù)庫在操作少量測(cè)試數(shù)據(jù)和大量數(shù)據(jù)的時(shí)候,表現(xiàn)行為上有很大的差異。通常,在開發(fā)過程前期,人們不會(huì)關(guān)注數(shù)據(jù)庫性能的問題,但是隨著時(shí)間的發(fā)展,人們必須采取一些措施來保證數(shù)據(jù)庫在大量數(shù)據(jù)的情況下正常工作。

Derby這個(gè)完全Java開發(fā)的開源的數(shù)據(jù)庫也不例外,因此你必須保證它不會(huì)成為你程序的一個(gè)瓶頸。盡管人們可以在Derby的手冊(cè)中找到關(guān)于這 個(gè)話題全面的資料,我還是想更詳盡的關(guān)注一下這些問題,基于我的經(jīng)驗(yàn)提供一些具體的例子。本文將著重于那些由在大的數(shù)據(jù)表中選擇查詢數(shù)據(jù)而產(chǎn)生的程序性能 問題。

首先,有很多關(guān)于調(diào)整Derby屬性(諸如頁面大小和緩存大小等)的技巧。修改這些參數(shù)可以在一定程度上調(diào)整數(shù)據(jù)庫的性能,但是在通常情況下,更主要的問題來自與你的程序和數(shù)據(jù)庫的設(shè)計(jì),因此,我們必須首先關(guān)注這些問題,最后再來考慮Derby的屬性。

在接下來的段落里,我將介紹一些能夠優(yōu)化程序中有問題部分的技術(shù)。但是,和其他性能優(yōu)化操作一樣,我們需要在優(yōu)化前先測(cè)量并確認(rèn)問題所在。

一個(gè)簡(jiǎn)單的例子

讓我們從一個(gè)簡(jiǎn)單的例子開始:假設(shè)我們Web程序中擁有一個(gè)“search/list”的頁面,要處理一個(gè)有接近100,000行的表,并且那個(gè)表 不是很小的(至少有10欄)。用簡(jiǎn)單的JDBC來寫一個(gè)例子,這樣我們可以專注在數(shù)據(jù)庫和JDBC問題上來。這篇文章中介紹的所有準(zhǔn)則對(duì)所有的面向?qū)ο蟮?映射工具都適用。

為了使得用戶能夠列出一個(gè)大的表,通常使用下面簡(jiǎn)單的查詢語句。 select * from tbl


對(duì)應(yīng)的JDBC語句如下:Class.forName("org.apache.derby.jdbc.ClientDriver").newInstance();
Connection connection = DriverManager.getConnection (
"jdbc:derby://localhost:1527/testDb;");
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("select * from tbl");
ArrayList allResults = new ArrayList();
while (rs.next()) {
// Object-Relation mapping code to populate your
// object from result set row
DomainObject domainObject = populate(rs);
allResults.add(modelObject);
}
System.out.println("Results Size: " + allResults.size());


在這兒,我們碰到了第一個(gè)問題。執(zhí)行這樣的代碼,并產(chǎn)生100,000(或更多)個(gè)domain對(duì)象將肯定會(huì)導(dǎo)致java用完堆棧空間,產(chǎn)生一個(gè) “java.lang.OutOfMemoryError”的錯(cuò)誤。對(duì)于初學(xué)者來說,我們首先必須找到一個(gè)方法來使得這個(gè)程序工作。

分頁Result Sets

隨著程序中數(shù)據(jù)量的增多,你首先想到的應(yīng)該做的事就是為特定的記錄(通常是視圖)提供分頁支持。正如你在這個(gè)介紹性的例子中看到的,簡(jiǎn)單地去獲取龐大的result sets很容易導(dǎo)致 out of memory的錯(cuò)誤。

許多數(shù)據(jù)庫服務(wù)器支持特定的SQL結(jié)構(gòu),它們可以用于獲得一個(gè)查詢結(jié)果的特定的子集。例如,在MySQL中,提供了LIMIT和OFFSET關(guān)鍵字,它們可以用于select查詢。因此,如果你執(zhí)行類似下面的查詢:select * from tbl LIMIT 50 OFFSET 100 


你的結(jié)果集將包含從第100個(gè)結(jié)果開始的50行,即使原先的查詢返回了100,000行。許多其他的數(shù)據(jù)庫提供商通過不同的結(jié)構(gòu)提供了相似的功能。 不幸的是,Derby并沒有提供這樣的功能,所以你必須繼續(xù)使用原先的“select * from tbl”查詢語句,然后在應(yīng)用程序中實(shí)現(xiàn)一個(gè)分頁的機(jī)制。讓我們來看下面的例子:Class.forName("org.apache.derby.jdbc.ClientDriver").newInstance();
Connection connection = DriverManager.getConnection(
"jdbc:derby://localhost:1527/testDb;");
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM tbl");
ArrayList allResults = new ArrayList();
int i = 0;
while (rs.next()) {
if (i > 50 && i <= 100) {
// O-R mapping code populate your row from result set
DomainObject domainObject = populate(rs);
allResults.add(modelObject);
}
i++;
}
System.out.println("Results Size: " + allResults.size());


通過這些額外的語句,我們提供了“分頁”的功能。盡管所有的結(jié)果都從數(shù)據(jù)庫服務(wù)器中取出了,但是只有那些我們感興趣的行才真正的映射到了Java的 對(duì)象中。現(xiàn)在我們避免了先前碰到的“OutOfMemoryError”的問題了,這樣保證了我們的程序可以真正的工作在大的數(shù)據(jù)表上。

然而,通過這個(gè)解決方案,數(shù)據(jù)庫仍然會(huì)掃描整個(gè)表,然后返回所有的行,這還是一個(gè)非常消耗時(shí)間的任務(wù)。對(duì)于我的事例數(shù)據(jù)庫來說,這個(gè)操作的執(zhí)行要花費(fèi)10秒鐘,這在程序中顯然是不可接受的。

因此,我們必須給出一個(gè)解決方案;我們并不需要返回所有的數(shù)據(jù)庫行,而只需要那些我們感興趣的(或者至少是所有行的最小可能子集)。我們這兒使用的 技巧就是顯式的告訴JDBC驅(qū)動(dòng)我們需要多少行。我們可以使用java.sql.Statement接口提供的setMaxRows()函數(shù)來完成這個(gè)任 務(wù)。看下面的例子:Class.forName("org.apache.derby.jdbc.ClientDriver").newInstance();
Connection connection = DriverManager.getConnection(
"jdbc:derby://localhost:1527/testDb;");
Statement stmt = connection.createStatement();
stmt.setMaxRows(101);
ResultSet rs = stmt.executeQuery("SELECT * FROM tbl");
ArrayList allResults = new ArrayList();
int i = 0;
while (rs.next()) {
if (i > 50 && i <= 100) {
// O-R mapping code populate your row from result set
DomainObject domainObject = populate(rs);
allResults.add(modelObject);
}
}
System.out.println("Results Size: " + allResults.size());


值得注意的是,我們把最大行的值設(shè)置為了我們需要的最后一行(增加了1)。因此,通過這樣的解決方案,我們不是僅僅取得了我們想要的50行,而是先 獲取了100行,然后從中篩選出我們感興趣的50行。不幸的是,我們沒有辦法告訴JDBC驅(qū)動(dòng)從一個(gè)具體的行開始,因此我們必須說明要顯示的記錄的最大行 數(shù)。這就意味著返回最初的一些記錄的操作的性能是很好的,但是隨著用戶瀏覽的結(jié)果的增多,性能也會(huì)下降。好消息就是在大多數(shù)的情形下,用戶不會(huì)瀏覽的太多 的記錄,他們會(huì)在前幾條記錄重獲得他們尋找的行,或者改變查詢策略。在我本人的環(huán)境中,上述的例子的執(zhí)行時(shí)間從8秒降到了0.8秒。

這是一個(gè)描述如何瀏覽整個(gè)表的簡(jiǎn)單的例子。但是當(dāng)查詢語句中增加了特定的where條件和排序信息時(shí),事情又開始變化了。在接下來的部分里,我將解釋為什么這種情況會(huì)發(fā)生,以后我們?nèi)绾伪WC在那些例子中獲得可接受的性能。
確保使用索引(避免全表掃描)

索引在數(shù)據(jù)庫設(shè)計(jì)中是一個(gè)非常重要的概念。因?yàn)楸疚乃婕暗姆秶邢蓿也⒉粫?huì)詳細(xì)的介紹索引理論。簡(jiǎn)單來說,索引是特定的數(shù)據(jù)庫結(jié)構(gòu),能夠允許對(duì) 表中的行進(jìn)行快速訪問。索引通常是在一欄或多欄上創(chuàng)建的,因?yàn)樗麄儽日麄€(gè)表小了很多,他們的主要用處就是快速搜索一欄(多欄)中的值。

Derby自動(dòng)的為主鍵和外鍵的欄以及具有唯一性限制的欄創(chuàng)建索引。對(duì)于其他任何欄,我們必須顯式的創(chuàng)建索引。在接下來的段落中,我們將研究一些例子來介紹索引在什么時(shí)候有用以及為什么有用。

但是首先,我們必須做一些準(zhǔn)備。在我們開始優(yōu)化之前,我們需要能夠了解我們執(zhí)行查詢操作的時(shí)候數(shù)據(jù)庫中發(fā)生了什么。Derby提供了 derby.language.logQueryPlan這個(gè)參數(shù)。如果設(shè)置了這個(gè)參數(shù),Derby將會(huì)把所有執(zhí)行的查詢的查詢計(jì)劃(query plan)記錄在derby.log這個(gè)文件中(這個(gè)文件在derby.system.home文件夾中)。我們可以在啟動(dòng)服務(wù)器之前通過合適的 derby.properties文件或者執(zhí)行如下的java語句來設(shè)置該參數(shù)。 System.setProperty("derby.language.logQueryPlan", "true");


通過檢查查詢計(jì)劃,我們可以觀察Derby在查詢中是使用了索引還是進(jìn)行了全表查詢,全表查詢是一個(gè)很耗時(shí)間的操作。

既然我們已經(jīng)設(shè)置好了環(huán)境,我們可以開始我們的例子了。假設(shè)我們先前使用的表 tb1中有一個(gè)沒有索引的欄叫做owner。因?yàn)閷?duì)查詢結(jié)果的排序通常是查詢性能低下的主要原因,我將介紹所有與排序有關(guān)的優(yōu)化。現(xiàn)在,如果我們希望修改 先前的例子來根據(jù)這一欄的值來排序我們的結(jié)果,我們需要把我們的查詢語句改成如下的樣子: SELECT * FROM tbl ORDER BY owner


如果我們用這個(gè)查詢語句代替先前的語句,執(zhí)行的時(shí)間將是先前的好多倍。盡管我們分頁(paginated)了所有的結(jié)果,并小心的設(shè)置了要獲取的行數(shù),總的執(zhí)行時(shí)間將會(huì)是8秒。

如果我們查看derby.log文件中查詢執(zhí)行計(jì)劃,我們可以輕易的發(fā)現(xiàn)問題:Table Scan ResultSet for TBL at read committed isolation
level using instantaneous share row locking chosen
by the optimizer


這意味著Derby為了將記錄排序,是在整個(gè)表中執(zhí)行了查找這個(gè)操作。那我們可以做些什么來改善這個(gè)情況呢?答案很簡(jiǎn)單,在這一欄上創(chuàng)建一個(gè)索引。我們可以通過如下的SQL語句來做這件事: CREATE INDEX tbl_owner ON tbl(owner)


如果我們重復(fù)我們先前的例子,我們將得到一個(gè)和我們沒有做排序前的那個(gè)例子相似的結(jié)果(在我的機(jī)器上是不到1秒)。

同樣,如果你現(xiàn)在查詢derby.log,你將看到下面的信息(而不是和上面的一樣的):Index Scan ResultSet for TBL using index TBL_OWNER
at read committed isolation level using share row locking
chosen by the optimizer


這就意味著我們可以確保Derby使用了剛創(chuàng)建的索引來獲取合適的行。

使用合適的索引順序

我們已經(jīng)看到了索引是如何幫助我們改善了排序某一欄數(shù)據(jù)時(shí)的性能。但是如果我們嘗試去反轉(zhuǎn)排序的順序的時(shí)候會(huì)發(fā)生什么呢?假設(shè)我們希望根據(jù)owner欄降序分類我們的數(shù)據(jù)。在這種情況下,我們?cè)鹊牟樵兙蜁?huì)變成如下的語句: SELECT * FROM tbl ORDER BY owner DESC


注意,我們?cè)黾恿薉ESC這個(gè)關(guān)鍵字,該關(guān)鍵字將按降序來排序我們的結(jié)果。如果我們執(zhí)行這個(gè)新修改過的查詢語句,將會(huì)發(fā)現(xiàn)整個(gè)執(zhí)行的時(shí)間又增加到先前的8-9秒。并且,在日志文件中,你將會(huì)發(fā)現(xiàn)又是執(zhí)行了全表掃描。

解決的方法就是為這一欄創(chuàng)建一個(gè)降序的索引。對(duì)于我們的owner欄,我們執(zhí)行如下的SQL語句。 CREATE INDEX tbl_owner_desc ON tbl(owner desc)


現(xiàn)在我們對(duì)這一欄有兩個(gè)索引了(兩個(gè)順序),因此查詢性能又恢復(fù)到了可接受的范圍了。注意查詢?nèi)罩局羞@一行:Index Scan ResultSet for TBL using index TBL_OWNER_DESC
at read committed isolation level using share row locking
chosen by the optimizer
這使我們確信我們使用了新建的索引。因此,如果你經(jīng)常要對(duì)結(jié)果進(jìn)行降序排序的話,你應(yīng)該考慮創(chuàng)建一個(gè)合適的索引來獲取更高的性能。
轉(zhuǎn)自:
http://space.itpub.net/?uid-47598-action-viewspace-itemid-207379
posted on 2009-11-24 16:40 chatler 閱讀(1840) 評(píng)論(0)  編輯 收藏 引用 所屬分類: Database
<2010年11月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

常用鏈接

留言簿(10)

隨筆分類(307)

隨筆檔案(297)

algorithm

Books_Free_Online

C++

database

Linux

Linux shell

linux socket

misce

  • cloudward
  • 感覺這個(gè)博客還是不錯(cuò),雖然做的東西和我不大相關(guān),覺得看看還是有好處的

network

OSS

  • Google Android
  • Android is a software stack for mobile devices that includes an operating system, middleware and key applications. This early look at the Android SDK provides the tools and APIs necessary to begin developing applications on the Android platform using the Java programming language.
  • os161 file list

overall

搜索

  •  

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲精品欧洲| 国产综合久久久久久| 久久成人资源| 一区二区激情| 亚洲国产高清视频| 久久久久女教师免费一区| 一本大道av伊人久久综合| 亚洲成人自拍视频| 国产日韩在线看| 国产精品jizz在线观看美国| 欧美jizz19性欧美| 久久亚洲国产成人| 欧美在线一二三四区| 亚洲午夜在线观看视频在线| 亚洲美女性视频| 亚洲国产日韩欧美| 欧美+日本+国产+在线a∨观看| 久久精品一区四区| 久久精品国产视频| 欧美一区二区三区的| 亚洲欧美综合| 亚洲女人小视频在线观看| 中文在线不卡视频| 99riav国产精品| 99热免费精品| 中日韩美女免费视频网址在线观看| 亚洲欧洲视频| 91久久久久久| 亚洲人成人一区二区三区| 91久久精品国产91性色| 亚洲国产成人久久| 亚洲欧洲精品一区二区三区不卡 | 欧美国产一区在线| 欧美va日韩va| 欧美激情日韩| 亚洲国产日韩欧美在线动漫| 欧美黑人国产人伦爽爽爽| 欧美成人蜜桃| 亚洲欧洲另类| 99精品欧美一区| 亚洲天堂偷拍| 欧美一级在线视频| 久久人体大胆视频| 麻豆精品在线视频| 欧美精品色综合| 国产精品扒开腿做爽爽爽视频| 欧美色视频日本高清在线观看| 国产精品扒开腿爽爽爽视频| 国产精品一卡二卡| 国内自拍一区| 最近看过的日韩成人| 一本色道久久综合狠狠躁篇的优点| 一本久久综合| 性亚洲最疯狂xxxx高清| 久久久久成人精品| 欧美成人tv| 亚洲精品在线视频| 亚洲已满18点击进入久久| 欧美亚洲自偷自偷| 毛片一区二区三区| 欧美视频中文字幕| 国产日韩精品一区二区三区| 亚洲成人中文| 亚洲小少妇裸体bbw| 欧美一区二区三区在| 免费亚洲电影| 99精品欧美| 久久精品日韩一区二区三区| 欧美高清在线一区二区| 国产精品久久久久久久久动漫| 国产亚洲一区二区在线观看| 亚洲另类在线视频| 欧美在线在线| 91久久精品美女高潮| 亚洲一区二区三区免费观看| 久久久久综合一区二区三区| 欧美肉体xxxx裸体137大胆| 国产视频不卡| 一区二区成人精品 | 亚洲国产成人不卡| 亚洲一区三区视频在线观看| 免费h精品视频在线播放| 国产精品扒开腿做爽爽爽视频| 韩国一区二区三区在线观看 | 久久精品一区二区三区四区 | 久久久久国产精品麻豆ai换脸| 欧美另类69精品久久久久9999| 国产丝袜一区二区| 宅男噜噜噜66一区二区66| 久久影视精品| 亚洲色图自拍| 欧美精品导航| 在线看成人片| 欧美一区二区视频网站| 亚洲精品国产拍免费91在线| 久久乐国产精品| 国产伦一区二区三区色一情| 日韩午夜在线播放| 美女精品一区| 亚洲一级免费视频| 欧美理论视频| 亚洲欧洲日韩综合二区| 久久精品中文| 亚洲自拍偷拍一区| 欧美日韩免费高清| 91久久精品国产91性色| 久久一区二区精品| 午夜精品久久久久久久蜜桃app | 亚洲国产美女精品久久久久∴| 欧美一区成人| 国产欧美精品在线播放| 在线视频亚洲欧美| 亚洲国产乱码最新视频| 久久天天躁狠狠躁夜夜av| 国产亚洲欧美激情| 欧美一区三区三区高中清蜜桃 | 亚洲福利免费| 裸体丰满少妇做受久久99精品| 国外视频精品毛片| 欧美伊人精品成人久久综合97| 一区电影在线观看| 欧美日韩成人综合在线一区二区 | 性一交一乱一区二区洋洋av| 亚洲视频免费在线| 欧美天天在线| 亚洲欧美另类久久久精品2019| 亚洲人成77777在线观看网| 欧美韩日一区二区| 日韩一区二区精品| 亚洲精品在线观看免费| 欧美久色视频| 亚洲性xxxx| 亚洲一区二区三区777| 国产精品美女午夜av| 香蕉尹人综合在线观看| 亚洲综合电影| 国内精品模特av私拍在线观看| 久久久国产一区二区| 久久精品夜色噜噜亚洲aⅴ| 怡红院av一区二区三区| 欧美成人一区二区| 欧美精品免费观看二区| 亚洲一二三四久久| 亚洲一区二区免费看| 国产日韩欧美亚洲一区| 美女91精品| 欧美激情精品久久久久久久变态| 99视频在线观看一区三区| 99国产精品久久久| 国产精一区二区三区| 久久久久久亚洲综合影院红桃| 久久在线免费视频| 999在线观看精品免费不卡网站| 一本久道久久综合狠狠爱| 国产伦精品一区二区三区高清版| 久久精品水蜜桃av综合天堂| 久久亚洲精品一区| 夜夜嗨av一区二区三区免费区| 亚洲天堂视频在线观看| 国产一区视频网站| 亚洲国产片色| 国产精品视频一| 欧美sm重口味系列视频在线观看| 欧美激情一区二区三级高清视频| 午夜久久久久久| 久久久久免费观看| 亚洲视频在线免费观看| 欧美亚洲一区二区三区| 亚洲日本在线观看| 亚洲免费影视第一页| 亚洲国产欧美不卡在线观看| av72成人在线| 在线观看日产精品| 亚洲视频免费在线观看| 在线观看av一区| 在线一区观看| 亚洲第一精品在线| 亚洲午夜精品17c| 亚洲国产日韩欧美综合久久 | 在线观看国产成人av片| 亚洲美女在线国产| 狠狠色伊人亚洲综合成人| 99精品国产高清一区二区 | 最新成人在线| 国产亚洲欧美一区二区| 亚洲欧洲精品一区| 伊人久久婷婷色综合98网| 99在线精品视频| 亚洲电影免费观看高清完整版在线观看 | 欧美裸体一区二区三区| 国产精品入口夜色视频大尺度| 免费成人av在线| 国产麻豆91精品| 亚洲精品五月天| 曰韩精品一区二区| 欧美激情 亚洲a∨综合| 国产老女人精品毛片久久| 亚洲人成久久| 在线免费观看日本一区| 亚洲欧美激情在线视频|