SQL Server數(shù)據(jù)庫如下方法來優(yōu)化查詢 :
1、把數(shù)據(jù)、日志、索引放到不同的I/O設(shè)備上,增加讀取速度,以前可以將Tempdb應(yīng)放在RAID0上,SQL2000不在支持。數(shù)據(jù)量(尺寸)越大,提高I/O越重要.
2、縱向、橫向分割表,減少表的尺寸(sp_spaceuse)
3、升級硬件
4、根據(jù)查詢條件,建立索引,優(yōu)化索引、優(yōu)化訪問方式,限制結(jié)果集的數(shù)據(jù)量。注意填充因子要適當(dāng)(最好是使用默認(rèn)值0)。索引應(yīng)該盡量小,使用字節(jié)數(shù)小的列建索引好(參照索引的創(chuàng)建),不要對有限的幾個值的字段建單一索引如性別字段
5、提高網(wǎng)速;
6、擴(kuò)大服務(wù)器的內(nèi)存,Windows 2000和SQL server 2000能支持4-8G的內(nèi)存。配置虛擬內(nèi)存:虛擬內(nèi)存大小應(yīng)基于計算機(jī)上并發(fā)運行的服務(wù)進(jìn)行配置。運行 Microsoft SQL Server? 2000 時,可考慮將虛擬內(nèi)存大小設(shè)置為計算機(jī)中安裝的物理內(nèi)存的 1.5 倍。如果另外安裝了全文檢索功能,并打算運行 Microsoft 搜索服務(wù)以便執(zhí)行全文索引和查詢,可考慮:將虛擬內(nèi)存大小配置為至少是計算機(jī)中安裝的物理內(nèi)存的 3 倍。將 SQL Server max server memory 服務(wù)器配置選項配置為物理內(nèi)存的 1.5 倍(虛擬內(nèi)存大小設(shè)置的一半)。
7、增加服務(wù)器 CPU個數(shù);但是必須明白并行處理串行處理更需要資源例如內(nèi)存。使用并行還是串行程是MsSQL自動評估選擇的。單個任務(wù)分解成多個任務(wù),就可以在處理器上運行。例如耽擱查詢的排序、連接、掃描和GROUP BY字句同時執(zhí)行,SQL SERVER根據(jù)系統(tǒng)的負(fù)載情況決定最優(yōu)的并行等級,復(fù)雜的需要消耗大量的CPU的查詢最適合并行處理。但是更新操作Update,Insert, Delete還不能并行處理。
8、如果是使用like進(jìn)行查詢的話,簡單的使用index是不行的,但是全文索引,耗空間。 like 'a%' 使用索引 like '%a' 不使用索引用 like '%a%' 查詢時,查詢耗時和字段值總長度成正比,所以不能用CHAR類型,而是VARCHAR。對于字段的值很長的建全文索引。
9、DB Server 和APPLication Server 分離;OLTP和OLAP分離
10、分布式分區(qū)視圖可用于實現(xiàn)數(shù)據(jù)庫服務(wù)器聯(lián)合體。聯(lián)合體是一組分開管理的服務(wù)器,但它們相互協(xié)作分擔(dān)系統(tǒng)的處理負(fù)荷。這種通過分區(qū)數(shù)據(jù)形成數(shù)據(jù)庫服務(wù)器聯(lián)合體的機(jī)制能夠擴(kuò)大一組服務(wù)器,以支持大型的多層 Web 站點的處理需要。有關(guān)更多信息,參見設(shè)計聯(lián)合數(shù)據(jù)庫服務(wù)器。(參照SQL幫助文件'分區(qū)視圖')
a、在實現(xiàn)分區(qū)視圖之前,必須先水平分區(qū)表
b、在創(chuàng)建成員表后,在每個成員服務(wù)器上定義一個分布式分區(qū)視圖,并且每個視圖具有相同的名稱。這樣,引用分布式分區(qū)視圖名的查詢可以在任何一個成員服務(wù)器上運行。系統(tǒng)操作如同每個成員服務(wù)器上都有一個原始表的復(fù)本一樣,但其實每個服務(wù)器上只有一個成員表和一個分布式分區(qū)視圖。數(shù)據(jù)的位置對應(yīng)用程序是透明的。
11、重建索引 DBCC REINDEX ,DBCC INDEXDEFRAG,收縮數(shù)據(jù)和日志 DBCC SHRINKDB,DBCC SHRINKFILE. 設(shè)置自動收縮日志.對于大的數(shù)據(jù)庫不要設(shè)置數(shù)據(jù)庫自動增長,它會降低服務(wù)器的性能。在T-sql的寫法上有很大的講究,下面列出常見的要點:首先,DBMS處理查詢計劃的過程是這樣的:
1、 查詢語句的詞法、語法檢查
2、 將語句提交給DBMS的查詢優(yōu)化器
3、 優(yōu)化器做代數(shù)優(yōu)化和存取路徑的優(yōu)化
4、 由預(yù)編譯模塊生成查詢規(guī)劃
5、 然后在合適的時間提交給系統(tǒng)處理執(zhí)行
6、 最后將執(zhí)行結(jié)果返回給用戶其次,看一下SQL SERVER的數(shù)據(jù)存放的結(jié)構(gòu):一個頁面的大小為8K(8060)字節(jié),8個頁面為一個盤區(qū),按照B樹存放。
12.commit和rollback的區(qū)別 Rollback:回滾所有的事物。 Commit:提交當(dāng)前的事物. 沒有必要在動態(tài)SQL里寫事物,如果要寫請寫在外面如: begin tran exec(@s) commit trans 或者將動態(tài)SQL 寫成函數(shù)或者存儲過程。
13、在查詢Select語句中用Where字句限制返回的行數(shù),避免表掃描,如果返回不必要的數(shù)據(jù),浪費了服務(wù)器的I/O資源,加重了網(wǎng)絡(luò)的負(fù)擔(dān)降低性能。如果表很大,在表掃描的期間將表鎖住,禁止其他的聯(lián)接訪問表,后果嚴(yán)重。
14、SQL的注釋申明對執(zhí)行沒有任何影響
15、盡可能不使用光標(biāo),它占用大量的資源。如果需要row-by-row地執(zhí)行,盡量采用非光標(biāo)技術(shù),如:在客戶端循環(huán),用臨時表,Table變量,用子查詢,用Case語句等等。游標(biāo)可以按照它所支持的提取選項進(jìn)行分類: 只進(jìn) 必須按照從第一行到最后一行的順序提取行。
FETCH NEXT 是唯一允許的提取操作,也是默認(rèn)方式。可滾動性可以在游標(biāo)中任何地方隨機(jī)提取任意行。游標(biāo)的技術(shù)在SQL2000下變得功能很強(qiáng)大,他的目的是支持循環(huán)。有四個并發(fā)選項 READ_ONLY:不允許通過游標(biāo)定位更新(Update),且在組成結(jié)果集的行中沒有鎖。 OPTIMISTIC WITH valueS:樂觀并發(fā)控制是事務(wù)控制理論的一個標(biāo)準(zhǔn)部分。樂觀并發(fā)控制用于這樣的情形,即在打開游標(biāo)及更新行的間隔中,只有很小的機(jī)會讓第二個用戶更新某一行。當(dāng)某個游標(biāo)以此選項打開時,沒有鎖控制其中的行,這將有助于最大化其處理能力。如果用戶試圖修改某一行,則此行的當(dāng)前值會與最后一次提取此行時獲取的值進(jìn)行比較。如果任何值發(fā)生改變,則服務(wù)器就會知道其他人已更新了此行,并會返回一個錯誤。如果值是一樣的,服務(wù)器就執(zhí)行修改。選擇這個并發(fā)選項OPTIMISTIC WITH ROW VERSIONING:此樂觀并發(fā)控制選項基于行版本控制。使用行版本控制,其中的表必須具有某種版本標(biāo)識符,服務(wù)器可用它來確定該行在讀入游標(biāo)后是否有所更改。在 SQL Server 中,這個性能由 timestamp 數(shù)據(jù)類型提供,它是一個二進(jìn)制數(shù)字,表示數(shù)據(jù)庫中更改的相對順序。每個數(shù)據(jù)庫都有一個全局當(dāng)前時間戳值:@@DBTS。每次以任何方式更改帶有 timestamp 列的行時,SQL Server 先在時間戳列中存儲當(dāng)前的 @@DBTS 值,然后增加 @@DBTS 的值。如果某 個表具有 timestamp 列,則時間戳?xí)挥浀叫屑墶7?wù)器就可以比較某行的當(dāng)前時間戳值和上次提取時所存儲的時間戳值,從而確定該行是否已更新。服務(wù)器不必比較所有列的值,只需比較 timestamp 列即可。如果應(yīng)用程序?qū)]有 timestamp 列的表要求基于行版本控制的樂觀并發(fā),則游標(biāo)默認(rèn)為基于數(shù)值的樂觀并發(fā)控制。 SCROLL LOCKS 這個選項實現(xiàn)悲觀并發(fā)控制。在悲觀并發(fā)控制中,在把數(shù)據(jù)庫的行讀入游標(biāo)結(jié)果集時,應(yīng)用程序?qū)⒃噲D鎖定數(shù)據(jù)庫行。在使用服務(wù)器游標(biāo)時,將行讀入游標(biāo)時會在其上放置一個更新鎖。如果在事務(wù)內(nèi)打開游標(biāo),則該事務(wù)更新鎖將一直保持到事務(wù)被提交或回滾;當(dāng)提取下一行時,將除去游標(biāo)鎖。如果在事務(wù)外打開游標(biāo),則提取下一行時,鎖就被丟棄。因此,每當(dāng)用戶需要完全的悲觀并發(fā)控制時,游標(biāo)都應(yīng)在事務(wù)內(nèi)打開。更新鎖將阻止任何其它任務(wù)獲取更新鎖或排它鎖,從而阻止其它任務(wù)更新該行。然而,更新鎖并不阻止共享鎖,所以它不會阻止其它任務(wù)讀取行,除非第二個任務(wù)也在要求帶更新鎖的讀取。滾動鎖根據(jù)在游標(biāo)定義的 Select 語句中指定的鎖提示,這些游標(biāo)并發(fā)選項可以生成滾動鎖。滾動鎖在提取時在每行上獲取,并保持到下次提取或者游標(biāo)關(guān)閉,以先發(fā)生者為準(zhǔn)。下次提取時,服務(wù)器為新提取中的行獲取滾動鎖,并釋放上次提取中行的滾動鎖。滾動鎖獨立于事務(wù)鎖,并可以保持到一個提交或回滾操作之后。如果提交時關(guān)閉游標(biāo)的選項為關(guān),則 COMMIT 語句并不關(guān)閉任何打開的游標(biāo),而且滾動鎖被保留到提交之后,以維護(hù)對所提取數(shù)據(jù)的隔離。所獲取滾動鎖的類型取決于游標(biāo)并發(fā)選項和游標(biāo) Select 語句中的鎖提示。鎖提示 只讀 樂觀數(shù)值 樂觀行版本控制 鎖定無提示 未鎖定 未鎖定 未鎖定 更新 NOLOCK 未鎖定 未鎖定未鎖定 未鎖定 HOLDLOCK 共享 共享 共享 更新 UPDLOCK 錯誤 更新 更新 更新 TABLOCKX 錯誤 未鎖定 未鎖定更新其它 未鎖定 未鎖定 未鎖定 更新 *指定 NOLOCK 提示將使指定了該提示的表在游標(biāo)內(nèi)是只讀的。
16、用Profiler來跟蹤查詢,得到查詢所需的時間,找出SQL的問題所在;用索引優(yōu)化器優(yōu)化索引
17、注意UNion和UNion all 的區(qū)別。UNION all好
18、注意使用DISTINCT,在沒有必要時不要用,它同UNION一樣會使查詢變慢。重復(fù)的記錄在查詢里是沒有問題的
19、查詢時不要返回不需要的行、列
20、用sp_configure 'query governor cost limit'或者SET QUERY_GOVERNOR_COST_LIMIT來限制查詢消耗的資源。當(dāng)評估查詢消耗的資源超出限制時,服務(wù)器自動取消查詢,在查詢之前就扼殺掉。 SET LOCKTIME設(shè)置鎖的時間
21、用select top 100 / 10 Percent 來限制用戶返回的行數(shù)或者SET ROWCOUNT來限制操作的行
22、在SQL2000以前,一般不要用如下的字句: "IS NULL", "<>", "!=", "!>", "!<", "NOT", "NOT EXISTS", "NOT IN", "NOT LIKE", and "LIKE '%500'",因為他們不走索引全是表掃描。也不要在Where字句中的列名加函數(shù),如Convert,substring等,如果必須用函數(shù)的時候,創(chuàng)建計算列再創(chuàng)建索引來替代.還可以變通寫法:Where SUBSTRING(firstname,1,1) = 'm'改為Where firstname like 'm%'(索引掃描),一定要將函數(shù)和列名分開。并且索引不能建得太多和太大。NOT IN會多次掃描表,使用EXISTS、NOT EXISTS ,IN , LEFT OUTER JOIN 來替代,特別是左連接,而Exists比IN更快,最慢的是NOT操作.如果列的值含有空,以前它的索引不起作用,現(xiàn)在2000的優(yōu)化器能夠處理了。相同的是IS NULL,"NOT", "NOT EXISTS", "NOT IN"能優(yōu)化她,而"<>"等還是不能優(yōu)化,用不到索引。
23、使用Query Analyzer,查看SQL語句的查詢計劃和評估分析是否是優(yōu)化的SQL。一般的20%的代碼占據(jù)了80%的資源,嚴(yán)重優(yōu)化的重點是這些慢的地方。
24、如果使用了IN或者OR等時發(fā)現(xiàn)查詢沒有走索引,使用顯示申明指定索引: Select * FROM PersonMember (INDEX = IX_Title) Where processid IN ('男','女')
25、將需要查詢的結(jié)果預(yù)先計算好放在表中,查詢的時候再Select。這在SQL7.0以前是最重要的手段。例如醫(yī)院的住院費計算。
26、MIN() 和 MAX()能使用到合適的索引。
27、數(shù)據(jù)庫有一個原則是代碼離數(shù)據(jù)越近越好,所以優(yōu)先選擇Default,依次為Rules,Triggers, Constraint(約束如外健主健CheckUNIQUE……,數(shù)據(jù)類型的最大長度等等都是約束),Procedure.這樣不僅維護(hù)工作小,編寫程序質(zhì)量高,并且執(zhí)行的速度快。
28、如果要插入大的二進(jìn)制值到Image列,使用存儲過程,千萬不要用內(nèi)嵌Insert來插入(不知JAVA是否)。因為這樣應(yīng)用程序首先將二進(jìn)制值轉(zhuǎn)換成字符串(尺寸是它的兩倍),服務(wù)器受到字符后又將他轉(zhuǎn)換成二進(jìn)制值.存儲過程就沒有這些動作: 方法:Create procedure p_insert as insert into table(Fimage) values (@image), 在前臺調(diào)用這個存儲過程傳入二進(jìn)制參數(shù),這樣處理速度明顯改善。
29、Between在某些時候比IN 速度更快,Between能夠更快地根據(jù)索引找到范圍。用查詢優(yōu)化器可見到差別。 select * from chineseresume where title in ('男','女') Select * from chineseresume where between '男' and '女' 是一樣的。由于in會在比較多次,所以有時會慢些。
30、在必要是對全局或者局部臨時表創(chuàng)建索引,有時能夠提高速度,但不是一定會這樣,因為索引也耗費大量的資源。他的創(chuàng)建同是實際表一樣。
31、不要建沒有作用的事物例如產(chǎn)生報表時,浪費資源。只有在必要使用事物時使用它。
32、用OR的字句可以分解成多個查詢,并且通過UNION 連接多個查詢。他們的速度只同是否使用索引有關(guān),如果查詢需要用到聯(lián)合索引,用UNION all執(zhí)行的效率更高.多個OR的字句沒有用到索引,改寫成UNION的形式再試圖與索引匹配。一個關(guān)鍵的問題是否用到索引。
33、盡量少用視圖,它的效率低。對視圖操作比直接對表操作慢,可以用stored procedure來代替她。特別的是不要用視圖嵌套,嵌套視圖增加了尋找原始資料的難度。我們看視圖的本質(zhì):它是存放在服務(wù)器上的被優(yōu)化好了的已經(jīng)產(chǎn)生了查詢規(guī)劃的SQL。對單個表檢索數(shù)據(jù)時,不要使用指向多個表的視圖,直接從表檢索或者僅僅包含這個表的視圖上讀,否則增加了不必要的開銷,查詢受到干擾.為了加快視圖的查詢,MsSQL增加了視圖索引的功能。
34、沒有必要時不要用DISTINCT和ORDER BY,這些動作可以改在客戶端執(zhí)行。它們增加了額外的開銷。這同UNION 和UNION ALL一樣的道理。
select top 20 ad.companyname,comid,position,ad.referenceid,worklocation, convert(varchar(10),ad.postDate,120) as postDate1,workyear,degreedescription FROM jobcn_query.dbo.COMPANYAD_query ad where referenceID in('JCNAD00329667','JCNAD132168','JCNAD00337748','JCNAD00338345',
83 <!---->
'JCNAD00333138','JCNAD00303570','JCNAD00303569',
'JCNAD00303568','JCNAD00306698','JCNAD00231935','JCNAD00231933',
'JCNAD00254567','JCNAD00254585','JCNAD00254608',
'JCNAD00254607','JCNAD00258524','JCNAD00332133','JCNAD00268618',
'JCNAD00279196','JCNAD00268613') order by postdate desc
35、在IN后面值的列表中,將出現(xiàn)最頻繁的值放在最前面,出現(xiàn)得最少的放在最后面,減少判斷的次數(shù)。
36、當(dāng)用Select INTO時,它會鎖住系統(tǒng)表(sysobjects,sysindexes等等),阻塞其他的連接的存取。創(chuàng)建臨時表時用顯示申明語句,而不是 select INTO. drop table t_lxh begin tran select * into t_lxh from chineseresume where name = 'XYZ' --commit 在另一個連接中Select * from sysobjects可以看到 Select INTO 會鎖住系統(tǒng)表,Create table 也會鎖系統(tǒng)表(不管是臨時表還是系統(tǒng)表)。所以千萬不要在事物內(nèi)使用它!!!這樣的話如果是經(jīng)常要用的臨時表請使用實表,或者臨時表變量。
37、一般在GROUP BY 個HAVING字句之前就能剔除多余的行,所以盡量不要用它們來做剔除行的工作。他們的執(zhí)行順序應(yīng)該如下最優(yōu):select 的Where字句選擇所有合適的行,Group By用來分組個統(tǒng)計行,Having字句用來剔除多余的分組。這樣Group By 個Having的開銷小,查詢快.對于大的數(shù)據(jù)行進(jìn)行分組和Having十分消耗資源。如果Group BY的目的不包括計算,只是分組,那么用Distinct更快
38、一次更新多條記錄比分多次更新每次一條快,就是說批處理好
39、少用臨時表,盡量用結(jié)果集和Table類性的變量來代替它,Table 類型的變量比臨時表好
40、在SQL2000下,計算字段是可以索引的,需要滿足的條件如下:
a、計算字段的表達(dá)是確定的
b、不能用在TEXT,Ntext,Image數(shù)據(jù)類型
c、必須配制如下選項 ANSI_NULLS = ON, ANSI_PADDINGS = ON, …….
41、盡量將數(shù)據(jù)的處理工作放在服務(wù)器上,減少網(wǎng)絡(luò)的開銷,如使用存儲過程。存儲過程是編譯好、優(yōu)化過、并且被組織到一個執(zhí)行規(guī)劃里、且存儲在數(shù)據(jù)庫中的SQL語句,是控制流語言的集合,速度當(dāng)然快。反復(fù)執(zhí)行的動態(tài)SQL,可以使用臨時存儲過程,該過程(臨時表)被放在Tempdb中。以前由于SQL SERVER對復(fù)雜的數(shù)學(xué)計算不支持,所以不得不將這個工作放在其他的層上而增加網(wǎng)絡(luò)的開銷。SQL2000支持UDFs,現(xiàn)在支持復(fù)雜的數(shù)學(xué)計算,函數(shù)的返回值不要太大,這樣的開銷很大。用戶自定義函數(shù)象光標(biāo)一樣執(zhí)行的消耗大量的資源,如果返回大的結(jié)果采用存儲過程
42、不要在一句話里再三的使用相同的函數(shù),浪費資源,將結(jié)果放在變量里再調(diào)用更快
43、Select COUNT(*)的效率教低,盡量變通他的寫法,而EXISTS快.同時請注意區(qū)別: select count(Field of null) from Table 和 select count(Field of NOT null) from Table 的返回值是不同的!!!
44、當(dāng)服務(wù)器的內(nèi)存夠多時,配制線程數(shù)量 = 最大連接數(shù)+5,這樣能發(fā)揮最大的效率;否則使用 配制線程數(shù)量<最大連接數(shù)啟用SQL SERVER的線程池來解決,如果還是數(shù)量 = 最大連接數(shù)+5,嚴(yán)重的損害服務(wù)器的性能。
45、按照一定的次序來訪問你的表。如果你先鎖住表A,再鎖住表B,那么在所有的存儲過程中都要按照這個順序來鎖定它們。如果你(不經(jīng)意的)某個存儲過程中先鎖定表B,再鎖定表A,這可能就會導(dǎo)致一個死鎖。如果鎖定順序沒有被預(yù)先詳細(xì)的設(shè)計好,死鎖很難被發(fā)現(xiàn)
46、通過SQL Server Performance Monitor監(jiān)視相應(yīng)硬件的負(fù)載 Memory: Page Faults / sec計數(shù)器如果該值偶爾走高,表明當(dāng)時有線程競爭內(nèi)存。如果持續(xù)很高,則內(nèi)存可能是瓶頸。
Process:
1、% DPC Time 指在范例間隔期間處理器用在緩延程序調(diào)用(DPC)接收和提供服務(wù)的百分比。(DPC 正在運行的為比標(biāo)準(zhǔn)間隔優(yōu)先權(quán)低的間隔)。 由于 DPC 是以特權(quán)模式執(zhí)行的,DPC 時間的百分比為特權(quán)時間百分比的一部分。這些時間單獨計算并且不屬于間隔計算總數(shù)的一部 分。這個總數(shù)顯示了作為實例時間百分比的平均忙時。
2、%Processor Time計數(shù)器 如果該參數(shù)值持續(xù)超過95%,表明瓶頸是CPU。可以考慮增加一個處理器或換一個更快的處理器。
3、% Privileged Time 指非閑置處理器時間用于特權(quán)模式的百分比。(特權(quán)模式是為操作系統(tǒng)組件和操縱硬件驅(qū)動程序而設(shè)計的一種處理模式。它允許直接訪問硬件和所有內(nèi)存。另一種模式為用戶模式,它是一種為應(yīng)用程序、環(huán)境分系統(tǒng)和整數(shù)分系統(tǒng)設(shè)計的一種有限處理模式。操作系統(tǒng)將應(yīng)用程序線程轉(zhuǎn)換成特權(quán)模式以訪問操作系統(tǒng)服務(wù))。特權(quán)時間的 % 包括為間斷和 DPC 提供服務(wù)的時間。特權(quán)時間比率高可能是由于失敗設(shè)備產(chǎn)生的大數(shù)量的間隔而引起的。這個計數(shù)器將平均忙時作為樣本時間的一部分顯示。
4、% User Time表示耗費CPU的數(shù)據(jù)庫操作,如排序,執(zhí)行aggregate functions等。如果該值很高,可考慮增加索引,盡量使用簡單的表聯(lián)接,水平分割大表格等方法來降低該值。 Physical Disk: Curretn Disk Queue Length計數(shù)器該值應(yīng)不超過磁盤數(shù)的1.5~2倍。要提高性能,可增加磁盤。 SQLServer:Cache Hit Ratio計數(shù)器該值越高越好。如果持續(xù)低于80%,應(yīng)考慮增加內(nèi)存。 注意該參數(shù)值是從SQL Server啟動后,就一直累加記數(shù),所以運行經(jīng)過一段時間后,該值將不能反映系統(tǒng)當(dāng)前值。
84 <!---->
47、分析select emp_name form employee where salary > 3000 在此語句中若salary是Float類型的,則優(yōu)化器對其進(jìn)行優(yōu)化為Convert(float,3000),因為3000是個整數(shù),我們應(yīng)在編程時使用3000.0而不要等運行時讓DBMS進(jìn)行轉(zhuǎn)化。同樣字符和整型數(shù)據(jù)的轉(zhuǎn)換。
48、查詢的關(guān)聯(lián)同寫的順序
select a.personMemberID, * from chineseresume a,personmember b where personMemberID = b.referenceid and a.personMemberID = 'JCNPRH39681' (A = B ,B = '號碼')
select a.personMemberID, * from chineseresume a,personmember b where a.personMemberID = b.referenceid and a.personMemberID = 'JCNPRH39681' and b.referenceid = 'JCNPRH39681' (A = B ,B = '號碼', A = '號碼')
select a.personMemberID, * from chineseresume a,personmember b where b.referenceid = 'JCNPRH39681' and a.personMemberID = 'JCNPRH39681' (B = '號碼', A = '號碼')
49、
(1)IF 沒有輸入負(fù)責(zé)人代碼 THEN code1=0 code2=9999 ELSE code1=code2=負(fù)責(zé)人代碼 END IF 執(zhí)行SQL語句為: Select 負(fù)責(zé)人名 FROM P2000 Where 負(fù)責(zé)人代碼>=:code1 AND負(fù)責(zé)人代碼 <=:code2
<clk></clk> (2)IF 沒有輸入負(fù)責(zé)人代碼 THEN Select 負(fù)責(zé)人名 FROM P2000 ELSE code= 負(fù)責(zé)人代碼 Select 負(fù)責(zé)人代碼 FROM P2000 Where 負(fù)責(zé)人代碼=:code END IF 第一種方法只用了一條SQL語句,第二種方法用了兩條SQL語句。在沒有輸入負(fù)責(zé)人代碼時,第二種方法顯然比第一種方法執(zhí)行效率高,因為它沒有限制條件; 在輸入了負(fù)責(zé)人代碼時,第二種方法仍然比第一種方法效率高,不僅是少了一個限制條件,還因相等運算是最快的查詢運算。我們寫程序不要怕麻煩
50、關(guān)于JOBCN現(xiàn)在查詢分頁的新方法(如下),用性能優(yōu)化器分析性能的瓶頸,如果在I/O或者網(wǎng)絡(luò)的速度上,如下的方法優(yōu)化切實有效,如果在CPU或者內(nèi)存上,用現(xiàn)在的方法更好。請區(qū)分如下的方法,說明索引越小越好。
begin
DECLARE @local_variable table (FID int identity(1,1),ReferenceID varchar(20))
insert into @local_variable (ReferenceID)
select top 100000 ReferenceID from chineseresume order by ReferenceID
select * from @local_variable where Fid > 40 and fid <= 60
end 和
begin
DECLARE @local_variable table (FID int identity(1,1),ReferenceID varchar(20))
insert into @local_variable (ReferenceID)
select top 100000 ReferenceID from chineseresume order by updatedate
select * from @local_variable where Fid > 40 and fid <= 60
end 的不同
begin
create table #temp (FID int identity(1,1),ReferenceID varchar(20))
insert into #temp (ReferenceID)
select top 100000 ReferenceID from chineseresume order by updatedate
select * from #temp where Fid > 40 and fid <= 60 drop table #temp
end
另附:存儲過程編寫經(jīng)驗和優(yōu)化措施 From:網(wǎng)頁教學(xué)網(wǎng)
一、適合讀者對象:數(shù)據(jù)庫開發(fā)程序員,數(shù)據(jù)庫的數(shù)據(jù)量很多,涉及到對SP(存儲過程)的優(yōu)化的項目開發(fā)人員,對數(shù)據(jù)庫有濃厚興趣的人。
二、介紹:在數(shù)據(jù)庫的開發(fā)過程中,經(jīng)常會遇到復(fù)雜的業(yè)務(wù)邏輯和對數(shù)據(jù)庫的操作,這個時候就會用SP來封裝數(shù)據(jù)庫操作。如果項目的SP較多,書寫又沒有一定的規(guī)范,將會影響以后的系統(tǒng)維護(hù)困難和大SP邏輯的難以理解,另外如果數(shù)據(jù)庫的數(shù)據(jù)量大或者項目對SP的性能要求很,就會遇到優(yōu)化的問題,否則速度有可能很慢,經(jīng)過親身經(jīng)驗,一個經(jīng)過優(yōu)化過的SP要比一個性能差的SP的效率甚至高幾百倍。
三、內(nèi)容:
1、開發(fā)人員如果用到其他庫的Table或View,務(wù)必在當(dāng)前庫中建立View來實現(xiàn)跨庫操作,最好不要直接使用“databse.dbo.table_name”,因為sp_depends不能顯示出該SP所使用的跨庫table或view,不方便校驗。
2、開發(fā)人員在提交SP前,必須已經(jīng)使用set showplan on分析過查詢計劃,做過自身的查詢優(yōu)化檢查。
3、高程序運行效率,優(yōu)化應(yīng)用程序,在SP編寫過程中應(yīng)該注意以下幾點:
a)SQL的使用規(guī)范:
i. 盡量避免大事務(wù)操作,慎用holdlock子句,提高系統(tǒng)并發(fā)能力。
ii. 盡量避免反復(fù)訪問同一張或幾張表,尤其是數(shù)據(jù)量較大的表,可以考慮先根據(jù)條件提取數(shù)據(jù)到臨時表中,然后再做連接。
iii. 盡量避免使用游標(biāo),因為游標(biāo)的效率較差,如果游標(biāo)操作的數(shù)據(jù)超過1萬行,那么就應(yīng)該改寫;如果使用了游標(biāo),就要盡量避免在游標(biāo)循環(huán)中再進(jìn)行表連接的操作。
iv. 注意where字句寫法,必須考慮語句順序,應(yīng)該根據(jù)索引順序、范圍大小來確定條件子句的前后順序,盡可能的讓字段順序與索引順序相一致,范圍從大到小。
v. 不要在where子句中的“=”左邊進(jìn)行函數(shù)、算術(shù)運算或其他表達(dá)式運算,否則系統(tǒng)將可能無法正確使用索引。
vi. 盡量使用exists代替select count(1)來判斷是否存在記錄,count函數(shù)只有在統(tǒng)計表中所有行數(shù)時使用,而且count(1)比count(*)更有效率。
vii. 盡量使用“>=”,不要使用“>”。
viii. 注意一些or子句和union子句之間的替換
ix. 注意表之間連接的數(shù)據(jù)類型,避免不同類型數(shù)據(jù)之間的連接。
x. 注意存儲過程中參數(shù)和數(shù)據(jù)類型的關(guān)系。
xi. 注意insert、update操作的數(shù)據(jù)量,防止與其他應(yīng)用沖突。如果數(shù)據(jù)量超過200個數(shù)據(jù)頁面(400k),那么系統(tǒng)將會進(jìn)行鎖升級,頁級鎖會升級成表級鎖。
b)索引的使用規(guī)范:
i. 索引的創(chuàng)建要與應(yīng)用結(jié)合考慮,建議大的OLTP表不要超過6個索引。
ii. 盡可能的使用索引字段作為查詢條件,尤其是聚簇索引,必要時可以通過index index_name來強(qiáng)制指定索引
iii. 避免對大表查詢時進(jìn)行table scan,必要時考慮新建索引。
iv. 在使用索引字段作為條件時,如果該索引是聯(lián)合索引,那么必須使用到該索引中的第一個字段作為條件時才能保證系統(tǒng)使用該索引,否則該索引將不會被使用。
v. 要注意索引的維護(hù),周期性重建索引,重新編譯存儲過程。
c)tempdb的使用規(guī)范:
i. 盡量避免使用distinct、order by、group by、having、join、cumpute,因為這些語句會加重tempdb的負(fù)擔(dān)。
ii. 避免頻繁創(chuàng)建和刪除臨時表,減少系統(tǒng)表資源的消耗。
iii. 在新建臨時表時,如果一次性插入數(shù)據(jù)量很大,那么可以使用select into代替create table,避免log,提高速度;如果數(shù)據(jù)量不大,為了緩和系統(tǒng)表的資源,建議先create table,然后insert。
iv. 如果臨時表的數(shù)據(jù)量較大,需要建立索引,那么應(yīng)該將創(chuàng)建臨時表和建立索引的過程放在單獨一個子存儲過程中,這樣才能保證系統(tǒng)能夠很好的使用到該臨時表的索引。
v. 如果使用到了臨時表,在存儲過程的最后務(wù)必將所有的臨時表顯式刪除,先truncate table,然后drop table,這樣可以避免系統(tǒng)表的較長時間鎖定。
vi. 慎用大的臨時表與其他大表的連接查詢和修改,減低系統(tǒng)表負(fù)擔(dān),因為這種操作會在一條語句中多次使用tempdb的系統(tǒng)表。
d)合理的算法使用:
根據(jù)上面已提到的SQL優(yōu)化技術(shù)和ASE Tuning手冊中的SQL優(yōu)化內(nèi)容,結(jié)合實際應(yīng)用,采用多種算法進(jìn)行比較,以獲得消耗資源最少、效率最高的方法。具體可用ASE調(diào)優(yōu)命令:set statistics io on, set statistics time on , set showplan on 等。
轉(zhuǎn)自:http://fableking.iteye.com/blog/360900
posted @
2011-08-13 12:41 [ 王志偉 ] 閱讀(285) |
評論 (0) |
編輯 收藏
北京聯(lián)高軟件開發(fā)有限公司 徐斌 王春晨
摘要:數(shù)據(jù)庫優(yōu)化不僅是數(shù)據(jù)庫管理員的任務(wù),程序員也必須知道一些優(yōu)化技巧,有利于開發(fā)高效的數(shù)據(jù)庫系統(tǒng)。
關(guān)鍵字:數(shù)據(jù)庫 優(yōu)化 技巧
如果是團(tuán)隊開發(fā),作為程序員必須知道本文描述的數(shù)據(jù)庫優(yōu)化技巧,如果你的sa水平比較差,那即使你再努力也些不出高效的數(shù)據(jù)庫應(yīng)用系統(tǒng)。
如果是單獨開發(fā),那就更不必說了。
多數(shù)公司的數(shù)據(jù)庫管理員(sa)是不夠格的,即使拿了各種認(rèn)證證件,也差不多還是垃圾管理員,無非是可以混個好職位,多拿一些工資。
如果你所在的公司沒有合格的sa,作為程序員的你必須執(zhí)行做許多數(shù)據(jù)庫優(yōu)化的工作了。
市面上的數(shù)據(jù)庫類圖書也不過是騙錢的把戲,無非為了出書而出書,為了出名而出書。
95%以上的作者沒有實踐的經(jīng)驗,99%以上的作者沒有優(yōu)化的經(jīng)驗。他們編寫圖書的來源無非是外文(不見得好啊)或者是互聯(lián)網(wǎng)上的資訊。
廢話不說了,開始吧。程序員級別的優(yōu)化有哪些手段?
(1)數(shù)據(jù)庫的設(shè)置:如果你的數(shù)據(jù)庫記錄數(shù)不會超過30萬條?如果你的數(shù)據(jù)庫記錄超過100萬條?該如何設(shè)置數(shù)據(jù)庫?一個或多個?
(2)數(shù)據(jù)庫表的設(shè)置:當(dāng)你的某個數(shù)據(jù)庫表記錄超過100萬級別,而且每天大量增長,這是一個不得不考慮的問題。如果你的系統(tǒng)瀏覽量很大,即使是30萬條記錄也是需要考慮的。
(3)索引的使用:索引可以大大提高數(shù)據(jù)庫訪問速度。什么時候用?哪些字段使用?
(4)存儲過程的使用:存儲過程終歸是比較好的,但是如果需要維護(hù)成百上千的存儲過程,未必是劃算的工程。
(5)高效的分頁技術(shù):數(shù)據(jù)庫記錄分頁列表是大量必須使用的基本技術(shù),怎樣的分頁是快速的?
宗旨你需要從上述5個方面考慮數(shù)據(jù)庫的優(yōu)化。
什么時候需要數(shù)據(jù)庫優(yōu)化?
(1)編寫代碼之前;
(2)系統(tǒng)速度慢了的時候;
下面就是一些具體的優(yōu)化技巧了。
(1)超大量記錄數(shù)據(jù)庫的優(yōu)化技巧 如果你的數(shù)據(jù)庫表記錄有超過100萬級別,而且不斷增長中。可以采取兩個手段:
第一:將數(shù)據(jù)庫表拆分到不同的庫中,比如 tblMEMBER 就可以拆分到 DB1 與 DB2 中去。
實際上,可以拆分到 DB001 ... DB100 甚至更多的庫中間去。
DB1 與 DB2 最好不在一塊硬盤上。
第二:如果更大量級的數(shù)據(jù),則最好拆分到不同的數(shù)據(jù)庫服務(wù)器中去。
數(shù)據(jù)庫的拆分帶來的是查詢等操作的復(fù)雜性。簡單地可以通過 hash 或者 按序號 匹配不同的數(shù)據(jù)庫。復(fù)雜一些,應(yīng)該設(shè)置一個獨立的應(yīng)用服務(wù)器(軟件)協(xié)調(diào)其中的操作。
(2)中等量級數(shù)據(jù)庫的優(yōu)化技巧 所謂中等量級數(shù)據(jù)庫是指數(shù)據(jù)庫100萬-500萬條記錄左右(單個數(shù)據(jù)庫表)。這樣的數(shù)據(jù)庫為了提高訪問(響應(yīng))速度,可以將表拆分到更小的表。比如 tblMEMBER 可以拆分為 tblMEMBER_00 ... tblMEMBER_99 。
這樣可以保證每個表的記錄數(shù)不超過50萬,那速度是"相當(dāng)"快了。
(3)避免使用視圖(viewport)與關(guān)聯(lián) 視圖viewport與關(guān)聯(lián)都是為了程序員處理相對復(fù)雜的數(shù)據(jù)管理提供方便的手段。萬物有其利,必有其弊。視圖和關(guān)聯(lián)提高了編程效率,都會較大地影響數(shù)據(jù)庫的訪問效率(事實上并不像一般資料說介紹的的那樣高效),因此如果是web應(yīng)用,則建議一般不要使用視圖與關(guān)聯(lián)。
(4)不要忘記索引(index)也不要濫用索引(index) 索引是提高數(shù)據(jù)庫效率的簡單又高效的方法。只要是設(shè)置了數(shù)據(jù)庫表(table),就不要忘記設(shè)置索引(index)。將索引設(shè)置在經(jīng)常用于排序的字段上,其他字段就不要設(shè)置了。
索引不是越多越好,也不是什么字段都適合建立索引的。數(shù)據(jù)重復(fù)性太多的字段不要設(shè)置索引。比如 tblMEMBER 的 iSex 字段只有 0 1 兩個值,就不要設(shè)置索引。
(5)二進(jìn)制的 text image 等字段應(yīng)該單獨設(shè)置別的表中 一般的數(shù)據(jù)庫應(yīng)用難免都需要保存比如描述、圖片等信息;一般描述類信息用 text 字段,圖片類信息用 image 字段;這里要說的是,不要將這些字段與其他字段放在一個表中。
比如:
1
tblMEMBER
2
id (int)
3
cName (varchar)(64)
4
cDescription (text)
5
bPhoto (image)
6
dDate (datetime)
7
就應(yīng)該拆分為3個表
8
tblMEMBER
9
id (int)
10
cName (varchar)(64)
11
dDate (datetime)
12
tblMEMBER_DESC
13
id (int)
14
cDescription (text)
15
dDate (datetime)
16
tblMEMBER_PHOTO
17
id (int)
18
bPhoto (image)
19
dDate (datetime)
20
(6)不要使用文本類型的 id 一般的數(shù)據(jù)庫表都會以一個種子字段作為主鍵。可以在與不少年青的程序員朋友溝通過程中,發(fā)現(xiàn)他們很喜歡用字符串類型的作為系統(tǒng)的 id 號。
比如:id = XX XX XX XX 這樣的字符串,每兩個位置代表不同的類別等含義。
不知道是那本教材如此誤人子弟,作出這樣的表率 :<
作為系統(tǒng)的 id 號,一定要使用數(shù)字型的。
(7)數(shù)據(jù)庫表table的字段field不要太多 本以為無需說明,也是發(fā)現(xiàn)不少的朋友,為了省事,一股腦把所有的相關(guān)字段都放在一個表中間。這樣做的后果便是,程序?qū)懫饋砗唵瘟耍\行效率下來了。
無論字段多少,有兩類字段是必須獨立出去的:一是進(jìn)程更新的字段,比如文章的點擊次數(shù)字段iShow,二是二進(jìn)制或者是text字段;
(8)將字符串(varchar)比較變成數(shù)字型(int)比較 每個系統(tǒng)都會有用戶管理,其中必然有 昵稱,密碼,郵件等的字符串類型數(shù)據(jù)比較的問題。在數(shù)據(jù)庫操作中,字符串比較的效率是相當(dāng)?shù)拖碌摹R虼擞龅阶址谋容^,必須將其轉(zhuǎn)換為數(shù)字型比較。
具體做法是:在數(shù)據(jù)庫表中增加相應(yīng)的數(shù)字字段,比如 cNickname -> iNickNumber ,其中 iNickNumber 的數(shù)值為 cNickname 的 哈希值(如何計算字符串的哈希值?請參閱本站的其他文章)。
通過這樣的轉(zhuǎn)換,系統(tǒng)效率可以提高 100 倍哦!!!
(9)為每個數(shù)據(jù)庫表(table)設(shè)置 datetime 字段 在許多情況下,很多的表是不需要 datetime 字段用于保存時間的。本文的建議是你應(yīng)該為每個表都設(shè)置 datetime 字段,而且默認(rèn)值為 getdate()。
我們的經(jīng)驗是,datetime 是實數(shù),占用字節(jié)不多;在進(jìn)行系統(tǒng)維護(hù),遠(yuǎn)程備份等環(huán)節(jié)都會發(fā)揮意想不到的效果。
(10)適當(dāng)使用存儲過程(Stored Processing) 存儲過程(sp)已經(jīng)被大大地宣傳了,本文也不例外地贊許采用存儲過程。本文的建議是只在下列情況才使用存儲過程:一是一個業(yè)務(wù)處理是事務(wù),包含了多個處理過程;二是一種處理被高頻使用,使用存儲過程可以提高效率;
(11)使用高效的分頁(ination)技術(shù) 數(shù)據(jù)庫記錄分頁列表是大量必須使用的基本技術(shù),因此本 文建議你在每個數(shù)據(jù)庫中建立下面的存儲過程:
1
CREATE PROCEDURE xsp_ination
2
(
3
@tblName varchar(64),
4
@strGetFields varchar(256) = "*",
5
@fldName varchar(64)="",
6
@PageSize int = 20,
7
@PageIndex int = 1,
8
@OrderType bit = 1,
9
@strWhere varchar(256) = ""
10
)
11
AS
12
BEGIN
13
declare @strSQL varchar(1000)
14
declare @strTmp varchar(110)
15
declare @strOrder varchar(400)
16
SET NOCOUNT ON
17
if @OrderType != 0
18
begin
19
set @strTmp = "<(select min"
20
set @strOrder = " order by [" + @fldName +"] desc"
21
end
22
else
23
begin
24
set @strTmp = ">(select max"
25
set @strOrder = " order by [" + @fldName +"] asc"
26
end
27
if @PageIndex = 1
28
begin
29
if @strWhere != ""
30
set @strSQL = "select top " + str(@PageSize) +" "+@strGetFields+ " from " + @tblName + " where " + @strWhere + " " + @strOrder
31
else
32
set @strSQL = "select top " + str(@PageSize) +" "+@strGetFields+ " from "+ @tblName + " "+ @strOrder
33
end
34
else
35
begin
36
set @strSQL = "select top " + str(@PageSize) +" "+@strGetFields+ " from "
37
+ @tblName + " where [" + @fldName + "]" + @strTmp + "(["+ @fldName + "]) from (select top " + str((@PageIndex-1)*@PageSize) + " ["+ @fldName + "] from " + @tblName + " " + @strOrder + ") as tblTmp)"+ @strOrder
38
if @strWhere != ""
39
set @strSQL = "select top " + str(@PageSize) +" "+@strGetFields+ " from "
40
+ @tblName + " where [" + @fldName + "]" + @strTmp + "(["
41
+ @fldName + "]) from (select top " + str((@PageIndex-1)*@PageSize) + " ["
42
+ @fldName + "] from " + @tblName + " where " + @strWhere + " "
43
+ @strOrder + ") as tblTmp) and " + @strWhere + " " + @strOrder
44
end
45
EXEC (@strSQL)
46
if @@error=0 return 1
47
SET NOCOUNT OFF
48
END
49
GO
50
使用方法是(C#):
sql = "EXEC [dbo].[xsp_ination] \"tblNEWS\",\"*\",\"id\",40," + pindex.ToString() + ",1,\"iType=" + type.ToString();
SqlDataReader sr = ExecuteReader(sql);
while (sr.Read())


{


}
sr.Close();

上面的優(yōu)化技巧僅是一些常見的手段,如果你的系統(tǒng)(小系統(tǒng)就算了)遇到效率問題,可以與聯(lián)高軟件聯(lián)系。
轉(zhuǎn)載本文請注明出處,以便遇到優(yōu)化困難的朋友可以找到聯(lián)高提供幫助。
posted @
2011-08-13 12:34 [ 王志偉 ] 閱讀(439) |
評論 (0) |
編輯 收藏
千萬人同時訪問的網(wǎng)站,一般是有很多個數(shù)據(jù)庫同時工作,說明白一點就是數(shù)據(jù)庫集群和并發(fā)控制,這樣的網(wǎng)站實時性也是相對的。這些網(wǎng)站都有一些共同的特點:數(shù)據(jù)量大,在線人數(shù)多,并發(fā)請求多,pageview高,響應(yīng)速度快。總結(jié)了一下各個大網(wǎng)站的架構(gòu),主要提高效率及穩(wěn)定性的幾個地方包括:
1、程序
程序開發(fā)是一方面,系統(tǒng)架構(gòu)設(shè)計(硬件+網(wǎng)絡(luò)+軟件)是另一方面。
軟件架構(gòu)方面,做網(wǎng)站首先需要很多web服務(wù)器存儲靜態(tài)資源,比如圖片、視頻、靜態(tài)頁等,千萬不要把靜態(tài)資源和應(yīng)用服務(wù)器放在一起。
一個好的程序員寫出來的程序會非常簡潔、性能很好,一個初級程序員可能會犯很多低級錯誤,這也是影響網(wǎng)站性能的原因之一。
網(wǎng)站要做到效率高,不光是程序員的事情,數(shù)據(jù)庫優(yōu)化、程序優(yōu)化這是必須的,在性能優(yōu)化上要數(shù)據(jù)庫和程序齊頭并進(jìn)!緩存也是兩方面同時入手。第一,數(shù)據(jù)庫緩存和數(shù)據(jù)庫優(yōu)化,這個由dba完成(而且這個有非常大的潛力可挖,只是由于我們都是程序員而忽略了他而已)。第二,程序上的優(yōu)化,這個非常的有講究,比如說重要一點就是要規(guī)范SQL語句,少用in 多用or,多用preparestatement 存儲過程,另外避免程序冗余如查找數(shù)據(jù)少用雙重循環(huán)等。另外選用優(yōu)秀的開源框架加以支持,我個人認(rèn)為中后臺的支持是最最重要的,可以選取spring+ibatis。因為ibatis直接操作SQL并有緩存機(jī)制。spring的好處就不用我多說了,IOC的機(jī)制可以避免new對象,這樣也節(jié)省開銷。據(jù)我分析,絕大部分的開銷就是在NEW的時候和連接數(shù)據(jù)庫時候產(chǎn)生的,請盡量避免。另外可以用一些內(nèi)存測試工具來做一個demo說明hibernate和ibatis誰更快!前臺你想用什么就用什么,struts,webwork都成,如果覺得自己挺牛X可以試試用tapestry。
用數(shù)據(jù)庫也未必不能解決訪問量巨大所帶來的問題,作成靜態(tài)文件硬盤的尋址時間也未必少于數(shù)據(jù)庫的搜索時間,當(dāng)然對資料的索引要下一翻工夫。我自己覺得門戶往往也就是當(dāng)天、熱門的資料點擊率較高,將其做緩存最多也不過1~2G的數(shù)據(jù)量吧,舉個例子:
◎ 拿網(wǎng)易新聞來說http://news.163.com/07/0606/09/3GA0D10N00011229.html
格式化一下,方便理解:http://域名/年/月日/新聞所屬分類/新聞ID.html
可以把當(dāng)天發(fā)布的、熱門的、瀏覽量大的作個緩存,用hashtable(key:年-月-日-分類-ID,value:新聞對象),靜態(tài)將其放到內(nèi)存(速度絕對快過硬盤尋址靜態(tài)頁面)。
通常是采用oracle存儲過程+2個weblogic,更新機(jī)制也幾乎一樣每簽發(fā)一條新聞,就會生成靜態(tài)頁面,然后發(fā)往前端的web服務(wù)器,前端的web都是做負(fù)載均衡的。另外還有定時程序,每5-15分鐘自動生成一次。在發(fā)布新聞的同時將數(shù)據(jù)緩存。當(dāng)然緩存也不會越來越大,在個特定的時間段(如凌晨)刪除過期的數(shù)據(jù)。做一個大的網(wǎng)站遠(yuǎn)沒有想象中那么簡單,服務(wù)器基本就要百十個的。
這樣可以大大增加一臺計算機(jī)的處理速度,如果一臺機(jī)器處理不了,可以用httpserver集群來解決問題了。
2、網(wǎng)絡(luò)
中國的網(wǎng)絡(luò)分南電信和北網(wǎng)通,訪問的ip就要區(qū)分南北進(jìn)入不同的網(wǎng)絡(luò)。
3、集群
通常會使用CDN與GSBL與DNS負(fù)載均衡技術(shù),每個地區(qū)一組前臺服務(wù)器群,比如新浪和搜狐,而網(wǎng)易,百度使用了DNS負(fù)載均衡技術(shù),每個頻道一組前臺服務(wù)器;一搜使用了DNS負(fù)載技術(shù),所有頻道共用一組前臺服務(wù)器集群。
網(wǎng)站使用基于Linux集群的負(fù)載均衡,失敗恢復(fù),包括應(yīng)用服務(wù)器和數(shù)據(jù)庫服務(wù)器,基于linux-ha的服務(wù)狀態(tài)檢測及高可用化。
應(yīng)用服務(wù)器集群可以采用apache+tomcat集群和weblogic集群等;web服務(wù)器集群可以用反向代理,也可以用NAT的方式,或者多域名解析都可以;Squid也可以,方法很多,可以根據(jù)情況選擇。
4、數(shù)據(jù)庫
因為是千萬人同時訪問的網(wǎng)站,所以一般是有很多個數(shù)據(jù)庫同時工作的,說明白一點就是數(shù)據(jù)庫集群和并發(fā)控制,數(shù)據(jù)分布到地理位置不同的數(shù)據(jù)中心,以免發(fā)生斷電事故。
主流的數(shù)據(jù)庫有Sun的是MySQL和Oracle。
Oracle是一款優(yōu)秀的、廣泛采用的商業(yè)數(shù)據(jù)庫管理軟件。有很強(qiáng)大的功能和安全性,可以處理相對海量的數(shù)據(jù)。而MySQL是一款非常優(yōu)秀的開源數(shù)據(jù)庫管理軟件,非常適合用多臺PC Server組成多點的存儲節(jié)點陣列(這里我所指的不是MySQL自身提供的集群功能),每單位的數(shù)據(jù)存儲成本也非常的低廉。用多臺PC Server安裝MySQL組成一個存儲節(jié)點陣列,通過MySQL自身的Replication或者應(yīng)用自身的處理,可以很好的保證容錯(允許部分節(jié)點失效),保證應(yīng)用的健壯性和可靠性。可以這么說,在關(guān)系數(shù)據(jù)庫管理系統(tǒng)的選擇上,可以考慮應(yīng)用本身的情況來決定。
MySQL數(shù)據(jù)庫服務(wù)器的master-slave模式,利用數(shù)據(jù)庫服務(wù)器在主從服務(wù)器間進(jìn)行同步,應(yīng)用只把數(shù)據(jù)寫到主服務(wù)器,而讀數(shù)據(jù)時則根據(jù)負(fù)載選擇一臺從服務(wù)器或者主服務(wù)器來讀取,將數(shù)據(jù)按不同策略劃分到不同的服務(wù)器(組)上,分散數(shù)據(jù)庫壓力。
另外還有一點的是,那些網(wǎng)站的靜態(tài)化網(wǎng)頁并不是真的,而是通過動態(tài)網(wǎng)頁與靜態(tài)網(wǎng)頁網(wǎng)址交換所出現(xiàn)的假象,這可以用urlrewrite這樣的開源網(wǎng)址映射器實現(xiàn)。這樣的網(wǎng)站實時性也是相對的,因為在數(shù)據(jù)庫復(fù)制數(shù)據(jù)的時候有一個過程,一般在技術(shù)上可以用到hibernate和ecache,但是如果要使網(wǎng)站工作地更好,可以使用EJB和websphere,weblogic這樣大型的服務(wù)器來支持,并且要用oracle這樣的大型數(shù)據(jù)庫。
大型門戶網(wǎng)站不建議使用Mysql數(shù)據(jù)庫,除非你對Mysql數(shù)據(jù)的優(yōu)化非常熟悉。Mysql數(shù)據(jù)庫服務(wù)器的master-slave模式,利用數(shù)據(jù)庫服務(wù)器在主從服務(wù)器間進(jìn)行同步,應(yīng)用只把數(shù)據(jù)寫到主服務(wù)器,而讀數(shù)據(jù)時則根據(jù)負(fù)載選擇一臺從服務(wù)器或者主服務(wù)器來讀取,將數(shù)據(jù)按不同策略劃分到不同的服務(wù)器(組)上,分散數(shù)據(jù)庫壓力。
大型網(wǎng)站要用oracle,數(shù)據(jù)方面操作盡量多用存儲過程,絕對提升性能;同時要讓DBA對數(shù)據(jù)庫進(jìn)行優(yōu)化,優(yōu)化后的數(shù)據(jù)庫與沒優(yōu)化的有天壤之別;同時還可以擴(kuò)展分布式數(shù)據(jù)庫,以后這方面的研究會越來越多;
5、頁面
從開始就考慮使用虛擬存儲/簇文件系統(tǒng)。它能讓你大量并行IO訪問,而且不需要任何重組就能夠增加所需要的磁盤。
頁面數(shù)據(jù)調(diào)用更要認(rèn)真設(shè)計,一些數(shù)據(jù)查詢可以不通過數(shù)據(jù)庫的方式,實時性要求不高的可以使用lucene來實現(xiàn),即使有實時性的要求也可以用lucene(基于Java的全文索引/檢索引擎),lucene+compass還是非常優(yōu)秀的。
新聞類的網(wǎng)站可以用靜態(tài)頁存儲,采用定時更新機(jī)制減輕服務(wù)器負(fù)擔(dān);首頁每個小模塊可以使用oscache緩存,這樣不用每次都拉數(shù)據(jù)。
前端的基于靜態(tài)頁面緩存的web加速器,主要應(yīng)用有squid等。squid 將大部分靜態(tài)資源(圖片,js,css等)緩存起來,直接返回給訪問者,減少應(yīng)用服務(wù)器的負(fù)載
網(wǎng)站的靜態(tài)化網(wǎng)頁并不是真的,而是通過動態(tài)網(wǎng)頁與靜態(tài)網(wǎng)頁網(wǎng)址交換做出現(xiàn)的假象,這可以用urlrewrite這樣的開源網(wǎng)址映射器實現(xiàn),后綴名為htm或者h(yuǎn)tml并不能說明程序生成了靜態(tài)頁面,可能是通過url重寫來實現(xiàn)的,為的只不過是在搜索引擎中提升自己網(wǎng)站的覆蓋面積罷了。
生成靜態(tài)頁面的服務(wù)器和www服務(wù)器是兩組不同的服務(wù)器,頁面生成后才會到www服務(wù)器,一部分?jǐn)?shù)據(jù)庫并不是關(guān)系數(shù)據(jù)庫,這樣更適合信息衍生,www、mail服務(wù)器、路由器多,主要用負(fù)載平衡解決訪問瓶頸。
◎ 靜態(tài)頁面的缺點:
1) 增加了程序的復(fù)雜度
2) 不利于管理資料
3) 速度不是最快
4) 傷硬盤
6、緩存
從一開始就應(yīng)該使用緩存,高速緩存是一個更好的地方存儲臨時數(shù)據(jù),比如Web站點上跟蹤一個特定用戶的會話產(chǎn)生的臨時文件,就不再需要記錄到數(shù)據(jù)庫里。
不能用lucene實現(xiàn)的可以用緩存,分布式緩存可以用memcached,如果有錢的話用10來臺機(jī)器做緩存,> 10G的存儲量相信存什么都夠了;如果沒錢的話可以在頁面緩存和數(shù)據(jù)緩存上下功夫,多用OSCACHE和EHCACHE,SWARMCACHE也可以,不過據(jù)說同步性不是很好;
可以使用Memcache(分布式緩存)進(jìn)行緩存,用大內(nèi)存把這些不變的數(shù)據(jù)全都緩存起來,而當(dāng)修改時就通知cache過期,memcache是LJ開發(fā)的一款分布式緩存產(chǎn)品,很多大型網(wǎng)站在應(yīng)用,我們可以把Cache Server與App Server裝在一起。因為Cache Server對CPU消耗不大,而有了Cache Server的支援,App Server對內(nèi)存要求也不是太高,所以可以和平共處,更有效的利用資源。
單機(jī)內(nèi)存緩存、文件緩存、數(shù)據(jù)庫緩存等的策略都是可以很簡單的實現(xiàn)的,例如可以使用微軟的Caching Application Block,但如何在集群環(huán)境中使多個緩存、多層緩存并保存同步是個重大問題。大型網(wǎng)站一般都使用緩存服務(wù)器群,并使用多層緩存。業(yè)內(nèi)最常用的有:
Squid cache,Squid服務(wù)器群,把它作為web服務(wù)器端前置cache服務(wù)器緩存相關(guān)請求來提高web服務(wù)器速度。Squid將大部分靜態(tài)資源(圖片,js,css等)緩存起來,直接返回給訪問者,減少應(yīng)用服務(wù)器的負(fù)載
memcache,memcache服務(wù)器群,一款分布式緩存產(chǎn)品,很多大型網(wǎng)站在應(yīng)用; 它可以應(yīng)對任意多個連接,使用非阻塞的網(wǎng)絡(luò)IO。由于它的工作機(jī)制是在內(nèi)存中開辟一塊空間,然后建立一個HashTable,Memcached自管理這些HashTable。因為通常網(wǎng)站應(yīng)用程序中最耗費時間的任務(wù)是數(shù)據(jù)在數(shù)據(jù)庫的檢索,而多個用戶查詢相同的SQL時,數(shù)據(jù)庫壓力會增大,而通過memcache的查詢緩存命中,數(shù)據(jù)直接從memcache內(nèi)存中取,每次緩存命中將替換到數(shù)據(jù)庫服務(wù)器的一次往返,到達(dá)數(shù)據(jù)庫服務(wù)器的請求更少,間接地提高了數(shù)據(jù)庫服務(wù)器的性能,從而使應(yīng)用程序運行得更快。它通過基于內(nèi)存緩存對象來減少數(shù)據(jù)庫查詢的方式改善網(wǎng)站系統(tǒng)的反應(yīng),其最吸引人的一個特性就是支持分布式部署。有關(guān)memcache,以下文章可以參考:參考1,參考2,參考3官方站點。
e-Accelerator,比較特殊,PHP的緩存和加速器。是一個免費開源的PHP加速、優(yōu)化、編譯和動態(tài)緩存的項目,它可以通過緩存PHP代碼編譯后的結(jié)果來提高PHP腳本的性能,使得一向很復(fù)雜和離我們很遠(yuǎn)的 PHP腳本編譯問題完全得到解決。通過使用eAccelerator,可以優(yōu)化你的PHP代碼執(zhí)行速度,降低服務(wù)器負(fù)載,可以提高PHP應(yīng)用執(zhí)行速度最高達(dá)10倍。
7、服務(wù)器操作系統(tǒng)與Web服務(wù)器
最底層首先是操作系統(tǒng)。好的操作系統(tǒng)能提高好的性能、穩(wěn)定性和安全性,而這些對大型網(wǎng)站的性能、安全性和穩(wěn)定性都是至關(guān)重要的。
- 淘寶網(wǎng)(阿里巴巴): Linux操作系統(tǒng) + Web 服務(wù)器: Apache
- 新浪:FreeBSD + Web 服務(wù)器:Apache
- Yahoo:FreeBSD + Web 服務(wù)器:自己的
- Google: 部分Linux + Web 服務(wù)器:自己的
- 百度:Linux + Web 服務(wù)器: Apache
- 網(wǎng)易:Linux + Web 服務(wù)器: Apache
- eBay: Windows Server 2003/8 (大量) + Web 服務(wù)器:Microsoft IIS
- MySpace: Windows Server 2003/8 + Web 服務(wù)器:Microsoft IIS
由此可見,開源操作系統(tǒng)做Web應(yīng)用是首選已經(jīng)是一個既定事實。在開源操作系統(tǒng)中Linux和FreeBSD差不太多,很難說哪個一定比另外一個要優(yōu)秀很多、能夠全面的超越對手,應(yīng)該是各有所長。但熟悉Linux的技術(shù)人員更多些,利于系統(tǒng)管理、優(yōu)化等,所以Linux使用更廣泛。而Windows Server和IIS雖然有的網(wǎng)站使用,但不開源,而且需要購買微軟的一系列應(yīng)用產(chǎn)品,限制了其使用。總之,開源操作系統(tǒng),尤其是Linux做Web應(yīng)用是首選已經(jīng)是一個既定事實。
常用的系統(tǒng)架構(gòu)是:
- Linux + Apache + PHP + MySQL
- Linux + Apache + Java (WebSphere) + Oracle
- Windows Server 2003/2008 + IIS + C#/ASP.NET + 數(shù)據(jù)庫
以上一些不太成熟的想法,可以從某一個層次開始,逐步細(xì)化,把產(chǎn)品的性能指標(biāo)提高上去。
轉(zhuǎn)自:
http://blog.sina.com.cn/s/blog_56fd58ab0100o2hw.html
posted @
2011-08-13 12:29 [ 王志偉 ] 閱讀(493) |
評論 (0) |
編輯 收藏
性能測試過程中,我們該如何監(jiān)控java虛擬機(jī)內(nèi)存的使用情況,用以判斷JVM是否存在內(nèi)存問題呢?如何判斷JVM垃圾回收是否正常?一般的top指令基本上滿足不了這樣的需求,因為它主要監(jiān)控的是總體的系統(tǒng)資源,很難定位到j(luò)ava應(yīng)用程序。
在項目實踐過程中,我們探索和使用了一款新工具--Jstat。
先秀一下。Jstat是JDK自帶的一個輕量級小工具。全稱“Java Virtual Machine statistics monitoring tool”,它位于java的bin目錄下,主要利用JVM內(nèi)建的指令對Java應(yīng)用程序的資源和性能進(jìn)行實時的命令行的監(jiān)控,包括了對Heap size和垃圾回收狀況的監(jiān)控。可見,Jstat是輕量級的、專門針對JVM的工具,非常適用。
那,該怎么用呢?
語法結(jié)構(gòu)如下:jstat [Options] vmid [interval] [count]
Options — 選項,我們一般使用 -gcutil 查看gc情況
vmid — VM的進(jìn)程號,即當(dāng)前運行的java進(jìn)程號
interval– 間隔時間,單位為秒或者毫秒
count — 打印次數(shù),如果缺省則打印無數(shù)次
下面給出一個實際的例子:
注:由于JVM內(nèi)存設(shè)置較大,圖中百分比變化不太明顯
圖中參數(shù)含義如下:
S0 — Heap上的 Survivor space 0 區(qū)已使用空間的百分比
S1 — Heap上的 Survivor space 1 區(qū)已使用空間的百分比
E — Heap上的 Eden space 區(qū)已使用空間的百分比
O — Heap上的 Old space 區(qū)已使用空間的百分比
P — Perm space 區(qū)已使用空間的百分比
YGC — 從應(yīng)用程序啟動到采樣時發(fā)生 Young GC 的次數(shù)
YGCT– 從應(yīng)用程序啟動到采樣時 Young GC 所用的時間(單位秒)
FGC — 從應(yīng)用程序啟動到采樣時發(fā)生 Full GC 的次數(shù)
FGCT– 從應(yīng)用程序啟動到采樣時 Full GC 所用的時間(單位秒)
GCT — 從應(yīng)用程序啟動到采樣時用于垃圾回收的總時間(單位秒)
上圖的示例,紅框中,我們可以看到,5次young gc之后,垃圾內(nèi)存被從Eden space區(qū)(E)放入了Old space區(qū)(O),并引起了百分比的變化,導(dǎo)致Survivor space使用的百分比從19.69%(S0)降到10.34%(S1)。有效釋放了內(nèi)存空間。綠框中,我們可以看到,一次full gc之后,Old space區(qū)(O)的內(nèi)存被回收,從36.81%降到35.01%。
圖中同時打印了young gc和full gc的總次數(shù)、總耗時。而,每次young gc消耗的時間,可以用相間隔的兩行YGCT相減得到。每次full gc消耗的時間,可以用相隔的兩行FGCT相減得到。例如紅框中表示的第一行、第二行之間發(fā)生了1次young gc,消耗的時間為52.281-52.252=0.029秒。
常駐內(nèi)存區(qū)(P)的使用率,始終停留在37.6%左右,說明常駐內(nèi)存沒有突變,比較正常。
如果young gc和full gc能夠正常發(fā)生,而且都能有效回收內(nèi)存,常駐內(nèi)存區(qū)變化不明顯,則說明java內(nèi)存釋放情況正常,垃圾回收及時,java內(nèi)存泄露的幾率就會大大降低。但也不能說明一定沒有內(nèi)存泄露。
以上,介紹了Jstat按百分比查看gc情況的功能。其實,它還有其它功能,例如加載類信息統(tǒng)計功能、內(nèi)存池信息統(tǒng)計功能等,那些是以絕對值的形式打印出來的,比較少用,在此就不做介紹。
為了更全面的監(jiān)控JVM內(nèi)存使用情況,我們需要引入更強(qiáng)大的工具來進(jìn)一步分析–JConsole。敬請關(guān)注。
--------
一、概述
SUN 的JDK中的幾個工具,非常好用。秉承著有免費,不用商用的原則。以下簡單介紹一下這幾種工具。(注:本文章下的所有工具都存在JDK5.0以上版本的工具集里,同javac一樣,不須特意安裝) 。
我一共找到以下四個工具:重點看看jconsole和jmap。
jps
:與unix上的ps類似,用來顯示本地的java進(jìn)程,可以查看本地運行著幾個java程序,并顯示他們的進(jìn)程號。
jstat
:一個極強(qiáng)的監(jiān)視VM內(nèi)存工具。可以用來監(jiān)視VM內(nèi)存內(nèi)的各種堆和非堆的大小及其內(nèi)存使用量。
jmap
:打印出某個java進(jìn)程(使用pid)內(nèi)存內(nèi)的,所有‘對象’的情況(如:產(chǎn)生那些對象,及其數(shù)量)。
jconsole
:一個java GUI監(jiān)視工具,可以以圖表化的形式顯示各種數(shù)據(jù)。并可通過遠(yuǎn)程連接監(jiān)視遠(yuǎn)程的服務(wù)器VM。
二、 使用介紹:
1、jstat :我想很多人都是用過unix系統(tǒng)里的ps命令,這個命令主要是用來顯示當(dāng)前系統(tǒng)的進(jìn)程情況,有哪些進(jìn)程,及其 id。 jps 也是一樣,它的作用是顯示當(dāng)前系統(tǒng)的java進(jìn)程情況,及其id號。我們可以通過它來查看我們到底啟動了幾個java進(jìn)程(因為每一個java程序都會獨占一個java虛擬機(jī)實例),和他們的進(jìn)程號(為下面幾個程序做準(zhǔn)備),并可通過opt來查看這些進(jìn)程的詳細(xì)啟動參數(shù)。
使用方法:在當(dāng)前命令行下打 jps(需要JAVA_HOME,沒有的話,到改程序的目錄下打) 。
可惜沒有l(wèi)inux下的ps好用,名稱不好用。但是在第四個工具jconsole的界面里面會有具體JAR包的名稱。
2、jstat :對VM內(nèi)存使用量進(jìn)行監(jiān)控。
jstat工具特別強(qiáng)大,有眾多的可選項,詳細(xì)查看堆內(nèi)各個部分的使用量,以及加載類的數(shù)量。使用時,需加上查看進(jìn)程的進(jìn)程id,和所選參數(shù)。以下詳細(xì)介紹各個參數(shù)的意義。
jstat -class pid:顯示加載class的數(shù)量,及所占空間等信息。
jstat -compiler pid:顯示VM實時編譯的數(shù)量等信息。
jstat -gc pid:可以顯示gc的信息,查看gc的次數(shù),及時間。其中最后五項,分別是young gc的次數(shù),young gc的時間,full gc的次數(shù),full gc的時間,gc的總時間。
jstat -gccapacity:可以顯示,VM內(nèi)存中三代(young,old,perm)對象的使用和占用大小,如:PGCMN顯示的是最小perm的內(nèi)存使用量,PGCMX顯示的是perm的內(nèi)存最大使用量,PGC是當(dāng)前新生成的perm內(nèi)存占用量,PC是但前perm內(nèi)存占用量。其他的可以根據(jù)這個類推, OC是old內(nèi)純的占用量。
jstat -gcnew pid:new對象的信息。
jstat -gcnewcapacity pid:new對象的信息及其占用量。
jstat -gcold pid:old對象的信息。
jstat -gcoldcapacity pid:old對象的信息及其占用量。
jstat -gcpermcapacity pid: perm對象的信息及其占用量。
jstat -util pid:統(tǒng)計gc信息統(tǒng)計。
jstat -printcompilation pid:當(dāng)前VM執(zhí)行的信息。
除了以上一個參數(shù)外,還可以同時加上 兩個數(shù)字,如:jstat -printcompilation 3024 250 6是每250毫秒打印一次,一共打印6次,還可以加上-h3每三行顯示一下標(biāo)題。
3、jmap 是一個可以輸出所有內(nèi)存中對象的工具,甚至可以將VM 中的heap,以二進(jìn)制輸出成文本。使用方法 jmap -histo pid。如果連用 SHELL jmap -histo pid>a.log可以將其保存到文本中去(windows下也可以使用),在一段時間后,使用文本對比工具,可以對比出GC回收了哪些對象。jmap -dump:format=b,file=f1 3024可以將3024進(jìn)程的內(nèi)存heap輸出出來到f1文件里。
4、jconsole 是一個用java寫的GUI程序,用來監(jiān)控VM,并可監(jiān)控遠(yuǎn)程的VM,非常易用,而且功能非常強(qiáng)。由于是GUI程序,這里就不詳細(xì)介紹了,不會的地方可以參考SUN的官方文檔。
使用方法:命令行里打 jconsole,選則進(jìn)程就可以了。
友好提示:windows查看進(jìn)程號,由于任務(wù)管理器默認(rèn)的情況下是不顯示進(jìn)程id號的,所以可以通過如下方法加上。ctrl+alt+del打開任務(wù)管理器,選擇‘進(jìn)程’選項卡,點‘查看’->''選擇列''->加上''PID'',就可以了。當(dāng)然還有其他很好的選項。
三、參考資料:
article:http://elf8848.javaeye.com/blog/442806
jps:http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jps.html
jstat:http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jstat.html
jmap:http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jmap.html
jconsole:http://java.sun.com/j2se/1.5.0/docs/guide/management/jconsole.html
posted @
2011-05-29 23:08 [ 王志偉 ] 閱讀(7500) |
評論 (0) |
編輯 收藏
PermGen space這一部分用于存放Class和Meta的信息,Class在被 Load的時候被放入PermGen space區(qū)域,它和和存放Instance的Heap區(qū)域不同,GC(Garbage Collection)不會在主程序運行期對PermGen space進(jìn)行清理,所以如果你的APP會LOAD很多CLASS的話,就很可能出現(xiàn)PermGen space錯誤。
我在做
TMS的發(fā)布工具的時候,就遇到了問題,這個工具的目的是把一個相同的系統(tǒng),在tomcat下自動的發(fā)布多份,但當(dāng)卸載,重新發(fā)布多次后, tomcat就掛了,整個電腦如同死機(jī)一般。后來使用文章里的set JAVA_OPTS=-server -Xms800m -Xmx800m -XX:PermSize=64M-XX:MaxNewSize=256m-XX:MaxPermSize=128m -Djava.awt.headless=true 解決了問題,不過在2G的電腦上,我是把-XX:MaxPermSize=128m 調(diào)到了-XX:MaxPermSize=256m。另外我還嘗試了把所有的lib都放到tomcat的lib下,一些lib就不能在本項目中再出現(xiàn)了。
現(xiàn)在看,還是spring,hibernate之類的產(chǎn)生的類導(dǎo)致PermGen space空間不足造成的這些問題。
http://www.javaeye.com/topic/80620?page=1 這個帖子里討論了這個問題,有人做了些有益的分析可以看看。
我又繼續(xù)在我的筆記本上做了測試T42,1G內(nèi)存。tomcat版本6.0.14。
set JAVA_OPTS=-server -Xms256m -Xmx256m -XX:PermSize=64M -XX:MaxNewSize=256m -XX:MaxPermSize=256m -Djava.awt.headless=true
這個配置反復(fù)發(fā)布是可以的,另外又一次測試了將項目下的jar包放到tomcat的lib下的對比。重新安裝一個lib下為空的程序是10秒,否則是30秒。
總結(jié)一下:
1、修改tomcat的啟動參數(shù),類似如下的樣子
set JAVA_OPTS=-server -Xms256m -Xmx256m -XX:PermSize=64M -XX:MaxNewSize=256m -XX:MaxPermSize=256m
echo Using CATALINA_BASE: %CATALINA_BASE%
echo Using CATALINA_HOME: %CATALINA_HOME%
echo Using CATALINA_TMPDIR: %CATALINA_TMPDIR%
if ""%1"" == ""debug"" goto use_jdk
echo Using JRE_HOME: %JRE_HOME%
goto java_dir_displayed
:use_jdk
echo Using JAVA_HOME: %JAVA_HOME%
:java_dir_displayed

echo Using JAVA_OPTS: %JAVA_OPTS%
set JAVA_OPTS=-server -Xms256m -Xmx256m -XX:PermSize=64M -XX:MaxNewSize=256m -XX:MaxPermSize=256m2、將通用的lib文件放到tomcat的目錄下
posted @
2011-05-29 23:05 [ 王志偉 ] 閱讀(364) |
評論 (0) |
編輯 收藏
POJO(Plain Old Java Object)這種叫法是Martin Fowler、Rebecca Parsons和Josh MacKenzie在2000年的一次演講的時候提出來的。
我在做J2EE培訓(xùn)中發(fā)現(xiàn)我的很多學(xué)生問我什么是POJO,后來我在寫書(《Spring2初學(xué)者實踐教材》和《Spring3初學(xué)者實踐教材》)的時候發(fā)現(xiàn)POJO這個概念無法回避。現(xiàn)在網(wǎng)上對于POJO的解釋很多,但是很多都是有錯誤的或者不夠準(zhǔn)確。對此我一開始也是存在誤區(qū)的,我原來是這樣理解的:
POJO是這樣的一種“純粹的”JavaBean,在它里面除了JavaBean規(guī)范的方法和屬性沒有別的東西,即private屬性以及對這個屬性方法的public的get和set方法。我們會發(fā)現(xiàn)這樣的JavaBean很“單純”,它只能裝載數(shù)據(jù),作為數(shù)據(jù)存儲的載體,而不具有業(yè)務(wù)邏輯處理的能力。
所以下面的代碼被認(rèn)為是POJO了。
package com.tongking.spring;
public class DbHello implements Hello {
private DictionaryDAO dao;
public void setDao(DictionaryDAO dao) {
this.dao = dao;
}
}
其實,這樣的認(rèn)為是錯誤的,我仔細(xì)閱讀了《POJOs in Action》這本書的有關(guān)部分和POJO的最原始的出處http://martinfowler.com/bliki/POJO.html,
The term was coined while Rebecca Parsons, Josh MacKenzie and I were preparing for a talk at a conference in September 2000. In the talk we were pointing out the many benefits of encoding business logic into regular java objects rather than using Entity Beans. We wondered why people were so against using regular objects in their systems and concluded that it was because simple objects lacked a fancy name. So we gave them one, and it''s caught on very nicely.
基本的意思是我們要給具有業(yè)務(wù)邏輯處理的規(guī)則的Java對象(regular java objects)起了一個名字——POJO,這些Java對象不是EntityBeans(EJB的一種)。
我又在http://www.webopedia.com/TERM/P/POJO.htm查到解釋如下:
POJO, or Plain Old Java Object, is a normal Java object class (that is, not a JavaBean, EntityBean etc.) and does not serve any other special role nor does it implement any special interfaces of any of the Java frameworks. This term was coined by Martin Fowler, Rebbecca Parsons and Josh MacKenzie who believed that by creating the acronym POJO, such objects would have a "fancy name", thereby convincing people that they were worthy of use.
基本意思是說POJO一個正規(guī)的Java對象(不是JavaBean,EntityBean等),也不擔(dān)當(dāng)任何的特殊的角色,也不實現(xiàn)任何Java框架指定的接口。
我覺得上面的解釋很準(zhǔn)確,POJO應(yīng)該不是我們開始認(rèn)為的JavaBean,當(dāng)然更不是EJB,它不應(yīng)該依賴于框架即繼承或?qū)崿F(xiàn)某些框架類或接口。例如:Struts1中的Action和ActionForm當(dāng)然不屬于POJO了,而在Struts2中的Action由于可以不繼承任何的接口,所以在這種情況下Action是POJO,但是Struts2中的Action也可以繼承ActionSupport類就不再屬于POJO了。POJO里面是可以包含業(yè)務(wù)邏輯處理和持久化邏輯,也可以包含類似與JavaBean屬性和對屬性訪問的set和get方法的。
最后,我們總結(jié)一下給一個定義把,POJO是一個簡單的、正規(guī)Java對象,它包含業(yè)務(wù)邏輯處理或持久化邏輯等,但不是JavaBean、EntityBean等,不具有任何特殊角色和不繼承或不實現(xiàn)任何其它Java框架的類或接口。
文章出處:飛諾網(wǎng)(www.firnow.com):http://dev.firnow.com/course/3_program/java/javashl/200845/108451.html
posted @
2011-04-19 11:00 [ 王志偉 ] 閱讀(356) |
評論 (0) |
編輯 收藏
非侵入式系介紹DI用語,我得理解是兩個組件(類,接口)之間,比較獨立,不深入到另一個類內(nèi)部,哪位大蝦能點撥一二?
關(guān)于“侵入式”和“非侵入式”設(shè)計
有讀者講“侵入式”這一術(shù)語無法理解,這里給一個簡單解釋,是我個人的看法。
在設(shè)計一個類時,按理說,需要考慮的應(yīng)該只是該類所企圖表示的那個“概念”本身:為表示有關(guān)概念應(yīng)記錄哪些信息,該類的對象與外界交換信息的界面等等。但定義這個類并不是為了放在那里觀賞,而是為了使用。在考慮類對象的使用時,使用環(huán)境的一些要素就可能“侵入”這個類的設(shè)計之中。實際上,許多情況下我們常常可以在“侵入式”設(shè)計和“非侵入式”設(shè)計之間做一個選擇,不同選擇各有優(yōu)缺點。在考慮非類的程序部分時,這種問題也同樣存在。
例如,我們可能需要對類A的對象做引用計數(shù),這里有兩種基本可能性:將計數(shù)功能納入類A的設(shè)計內(nèi)(侵入式引用計數(shù)設(shè)計,此時類A的對象中包含了與引用計數(shù)有關(guān)的要素,這顯然是與類A所要表示的概念無關(guān)的東西),或者將計數(shù)功能放在類A之外(非侵入式引用計數(shù))。
本書中討論容器時提出了“侵入式容器”設(shè)計和“非侵入式容器”設(shè)計的概念:當(dāng)我們希望將類A的對象放入一種容器時,是否需要將該容器的實現(xiàn)要素“侵入”類A的設(shè)計實現(xiàn)之中(這顯然是與類A本身并無必然關(guān)系的要素)。不同考慮導(dǎo)致不同的容器設(shè)計。
我基本上知道了,從夏大蝦得著作中得知。
比如struts,需要繼承一些struts得類,這就是侵入式,使得系統(tǒng)離不開那個框架。
而spring中,業(yè)務(wù)類不需要繼承框架得類,將來拋棄spring也比較方便。
樓上大蝦(土豆塊)能否談下ejb與spring之間得關(guān)系。你用ejb嗎?如果用了,感覺如何?
非侵入式(non-intrusive)設(shè)計是目前非常熱門的話題。在一般的討論中,非侵入式設(shè)計總是和Spring這樣的IoC容器或者AOP技術(shù)聯(lián)系在一起。但是從思想上說,non-intrusive并不等價于IoC或者AOP,它是一個比AOP更加寬泛的概念。
首先,我們考察一下何謂intrusive。典型的intrusive實現(xiàn)是繼承特定的基類, 或者實現(xiàn)特定的接口. 在抽象的意義上說, intrusive意味著在基礎(chǔ)結(jié)構(gòu)中預(yù)留了一些特殊的,專用的結(jié)構(gòu), 這些結(jié)構(gòu)對于基礎(chǔ)功能而言不僅僅是無用的, 甚至是有害的, 例如影響性能或者模糊了原有的概念結(jié)構(gòu), 而系統(tǒng)整體的后期擴(kuò)展能力也受到這些預(yù)設(shè)的結(jié)構(gòu)通道的限制.
non-intrusive設(shè)計的基本特點是盡量利用基礎(chǔ)結(jié)構(gòu)的元素, 而不是引入額外的特殊結(jié)構(gòu).例如, 在witrix平臺的tpl模板中
<button tpl:tag="ui:FlatButton" value="xx" onclick="alert('ok')" />
如果后臺tpl引擎不解析<ui:FlatButton>標(biāo)簽, 那么該標(biāo)簽的表現(xiàn)就是普通的html button. 這里整個頁面的界面表現(xiàn)結(jié)構(gòu)沒有被tpl標(biāo)簽所破壞,而如果像jsp tag那樣強(qiáng)行規(guī)定必須采用節(jié)點語法, 即
<ui:FlatButton value="xx" onclick="alert('ok')" />
則在沒有tpl引擎的情況下, 界面結(jié)構(gòu)被tpl標(biāo)簽所破壞,此時在dreamweaver這樣的可視化工具中我們無法再識別出有效的界面元素, 喪失了WYSIWYG編輯的能力.
tpl:tag屬性屬于html語法本身規(guī)定了的自定義屬性, 它在html中的存在是符合規(guī)范的, 而且它對于button來說沒有造成什么限制或損害, 因而是一種無害的標(biāo)記. 在沒有tpl模板引擎的情況下, tpl:tag屬性與其他自定義屬性一樣處于同樣的地位, 沒有什么特殊的作用. 而一旦tpl模板引擎識別出該特殊標(biāo)記, 整個節(jié)點就被解釋成一個具有豐富表現(xiàn)形式的平面按鈕而不是系統(tǒng)缺省風(fēng)格的普通按鈕. 從級列設(shè)計的角度上說, button對應(yīng)于ui:FlatButton在沒有tpl解析能力情況時退化了的結(jié)果. 在EJB3的規(guī)范中, 普通的POJO(Plain Old Java Object)對象在經(jīng)過無害的標(biāo)記(annotation)之后通過Enhance過程獲得持久化等特性, POJO正對應(yīng)于EJB Object的退化形式. 在某種意義上我們可以說, 存在著多少種可退化方式,就對應(yīng)著多少種non-intrusive design。
與傳統(tǒng)設(shè)計中的結(jié)構(gòu)堆砌不同, 現(xiàn)代技術(shù)更加強(qiáng)調(diào)在原有結(jié)構(gòu)基礎(chǔ)上的同態(tài)變化, 關(guān)注原有結(jié)構(gòu)中的某些部分出現(xiàn)特殊意義后所產(chǎn)生的對稱破缺. 在non-intrusive設(shè)計中, 基礎(chǔ)的結(jié)構(gòu)中沒有為擴(kuò)展內(nèi)置什么特殊的結(jié)構(gòu), 一般僅僅是標(biāo)記而已, 這些標(biāo)記是無害的甚至本身在基礎(chǔ)結(jié)構(gòu)中是有用的, 例如某些javascript庫在前臺html頁面中利用html標(biāo)簽的class屬性作為標(biāo)記. 為了識別這些屬于結(jié)構(gòu)標(biāo)準(zhǔn)部分的標(biāo)記并對之進(jìn)行處理,我們需要一種可選擇的結(jié)構(gòu)透明性, 具體來說我們需要能滲透到系統(tǒng)內(nèi)部,準(zhǔn)確的定位到標(biāo)記處. 這就類似于x光檢測, x光只與某些特殊材料發(fā)生強(qiáng)烈作用而普通部分對于x光而言是透明的. 而當(dāng)外部引擎識別出這些特殊的標(biāo)記之后, 可能需要操縱該局部結(jié)構(gòu), 例如在基礎(chǔ)結(jié)構(gòu)中插入一些新的結(jié)構(gòu)以實現(xiàn)基礎(chǔ)結(jié)構(gòu)的增強(qiáng). 這些都可能需要應(yīng)用類似于AOP的技術(shù), 而在這一增強(qiáng)過程中關(guān)于擴(kuò)展結(jié)構(gòu)的具體知識存在于擴(kuò)展引擎中而不是基礎(chǔ)結(jié)構(gòu)中, 因而往往整體表現(xiàn)出一種IoC的特性.
轉(zhuǎn)自:http://hi.baidu.com/westsky/blog/item/46d452f0127cebaaa50f522f.html
posted @
2011-04-19 10:23 [ 王志偉 ] 閱讀(4587) |
評論 (0) |
編輯 收藏