国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
談數(shù)據(jù)庫的性能優(yōu)化 - Database - Tech - JavaEye論壇

這個是我以前寫給我部門的一個技術(shù)心得,鄙人只是搞java開發(fā)的,不是專業(yè)的DBA,只是喜歡鉆研數(shù)據(jù)庫方面的的東西。

 

知道javaeye高人很多,如果我寫的不對的地方,歡迎友好討論,謝絕漫罵攻擊。

1:前言


      數(shù)據(jù)庫優(yōu)化是一個很廣的范圍,涉及到的東西比較多,并且每個特定的數(shù)據(jù)庫,其具體的優(yōu)化過程也是不一樣的.因為優(yōu)化的很大一部分最終都要跟具體的數(shù)據(jù)庫系統(tǒng)細節(jié)打交道,在此不可能針對所有的數(shù)據(jù)庫都一一詳細闡述,如果那樣,恐怕寫幾本書都寫不完.只能針對一些比較通用的,經(jīng)常用到的的東西進行一個討論,一般情況下,數(shù)據(jù)庫的優(yōu)化指的就是查詢性能的優(yōu)化(雖然嚴格上來說不應該是這樣的),讓數(shù)據(jù)庫對查詢的響應盡可能的快.僅對數(shù)據(jù)庫系統(tǒng)本身而言,影響到查詢性能的因素從理論上來講,包括數(shù)據(jù)庫參數(shù)設置(其實就是通過參數(shù)控制數(shù)據(jù)庫系統(tǒng)的內(nèi)存,i/o,緩存,備份等一些管理性的東西),索引,分區(qū),sql語句.數(shù)據(jù)庫參數(shù)設置本身是一個很復雜的東西,分區(qū)則主要是針對大數(shù)據(jù)量的情況下,它分散了數(shù)據(jù)文件的分布,減少磁盤競爭,使效率得到提升。


      每種數(shù)據(jù)庫或多或少都有一些自己特定的索引,如oracle除了常規(guī)索引之外還有反向索引,位圖索引,函數(shù)索引,應用程序域索引等等,能夠讓用戶對數(shù)據(jù)的邏輯組織有著更為精確的控制,而sqlserver沒有這么多的索引,大體來說,sqlserver的索引分為兩種:聚集索引和非聚集索引.在分區(qū)方面,oracle和sqlserver比較相似,不過sqlserver的分區(qū)更為繁瑣一些,但隨著sqlserver的版本越來越高,其分區(qū)操作也趨向于簡潔.sql語句優(yōu)化則基本上比較獨立,目前的一些數(shù)據(jù)庫系統(tǒng)處理sql的機制都比較類似,因為sql本身就是一個標準。這三種將會在下面作一個詳細的討論.本討論建立在sqlserver上,因為目前部門的很多系統(tǒng)的數(shù)據(jù)庫用到的是sqlserver,雖然oracle會給與我們更多的可探討的范圍.

 

 


2:測試數(shù)據(jù)庫的建立
      因為要討論索引,分區(qū),sql等,因此有必要建立一個數(shù)據(jù)庫,不然只是泛泛而談,我在sqlserver2000上建立了一個名為ipanel的數(shù)據(jù)庫,該數(shù)據(jù)庫只有一張表,名為person,person的定義如下:


CREATE TABLE [dbo].[person] (
[id] [bigint] NOT NULL , --記錄的id
[name] [varchar] (10) COLLATE Chinese_PRC_CI_AS NULL ,--姓名
[age] [int] NULL ,--年齡
[addr] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,--地址
[sex] [char] (10) COLLATE Chinese_PRC_CI_AS NULL ,--性別
[dept] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,--部門
[pos] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,--郵編
[tel] [char] (15) COLLATE Chinese_PRC_CI_AS NULL ,--電話
[fax] [char] (15) COLLATE Chinese_PRC_CI_AS NULL ,--傳真
[emdate] [datetime] NULL --入職日期
) ON [PRIMARY]


      ON[PRIMARY]表示該表建在系統(tǒng)的默認文件組上,在sqlserver里,文件組的概念就相當于oracle的表空間,是一種邏輯概念,它包含了數(shù)據(jù)文件,所謂數(shù)據(jù)文件,當然就是存儲數(shù)據(jù)的文件.默認情況下,sqlserver會在默認的路徑建立文件組和初始的數(shù)據(jù)文件,如果用戶在建立數(shù)據(jù)庫或表的時候沒有指定文件組,則用默認的。數(shù)據(jù)文件,日志文件,參數(shù)文件是所有數(shù)據(jù)庫系統(tǒng)最主要的文件,oracle還有控制文件,在很多的專業(yè)書籍里面,從數(shù)據(jù)庫系統(tǒng)的物理結(jié)構(gòu)上來講,數(shù)據(jù)庫就是指的靜態(tài)的數(shù)據(jù)文件,數(shù)據(jù)庫系統(tǒng)或者數(shù)據(jù)庫實例指的是一組進程,如日志進程,數(shù)據(jù)緩沖進程,網(wǎng)絡監(jiān)聽進程等,這些進程作用在各種文件上面。不說了,扯遠了.建了一個數(shù)據(jù)插入的存儲過程:

CREATE PROCEDURE initPerson @start int, @end int , --起始條數(shù),結(jié)束條數(shù)
@name varchar(10),@age int, --姓名,年齡
@addr varchar(10),@sex char(2), --地址,性別
@dept varchar(20),@emdate varchar(10 --部門,入職日期
AS
declare @id int
set @id=@start
while @id<=@end
begin
insert into person values(@id,@name,@age,@addr,@sex,@dept ,
'438200','82734664','82734665',@emdate)
set @id=@id+1
end
GO


以下插入記錄
exec initPerson 1,100000, ‘王**’,24,’深圳’,’男’,’應用開發(fā)部’,’2007-06-04’
插入10萬條名叫王**的記錄,因為在當前的例子中,姓名不重要,所以相同的姓名不礙事。如下依次執(zhí)行
exec initPerson 100001,200000, ‘韓**’,25,’深圳’,’男’,’應用工程部’,’2007-06-05’
exec initPerson 200001,300000, ‘徐*’,26,’ 深圳’,’男’,’系統(tǒng)終端部’,’2007-06-06’
exec initPerson 300001,500000, ‘程*’,23’, 深圳’,’男’,’研發(fā)中心’,’2007-06-07’
exec initPerson 500001,750000, ‘卓*’,22,’ 深圳’,’男’,’行政部’,’2007-06-08’
exec initPerson 750001,1000000, ‘流*’,20,’ 深圳’,’男’,’業(yè)務合作部’,’2007-06-09’
接著依次插入類似的記錄,我就不一一列舉了.
執(zhí)行完畢,person表便有了200萬條記錄。為什么我不用更多的數(shù)據(jù)呢,因為我要頻繁的改變數(shù)據(jù)庫的設置,如果數(shù)據(jù)非常多,那當我改變數(shù)據(jù)庫設置時候,會耗費很長的時間,比如索引更新維護等,不太方便.值得一提的是,如果沒有指定聚集索引,那么sqlserver默認在主鍵上建立聚集索引,在當前情況下,系統(tǒng)在id列上建立了聚集索引。
數(shù)據(jù)庫建立完畢,下面將會對索引,分區(qū),sql做比較詳細的討論

 

 

 

 

 


3:索引 

 

      索引是各種關系數(shù)據(jù)庫系統(tǒng)最常見的一種邏輯單元,是關系數(shù)據(jù)庫系統(tǒng)舉足輕重的重要組成部分,對于提高檢索數(shù)據(jù)速度有著至關重要的作用,索引的原理是根據(jù)索引值得到行指針,然后快速定位到數(shù)據(jù)庫記錄..

 


3.1:常見索引介紹

  

1: B*樹索引
      這是最常見的索引,幾乎所有的關系型數(shù)據(jù)庫系統(tǒng)都支持B*樹結(jié)構(gòu)的索引,也是被最多使用的,其樹結(jié)構(gòu)與二叉樹比較類似,根據(jù)行id快速定位到行.大部分數(shù)據(jù)庫默認建立的索引就是這種索引.B*樹索引在檢索高基數(shù)數(shù)據(jù)列(高基數(shù)列是指該列有很多不同的值,該列所有不同值的個數(shù)之和與該列所有值的個數(shù)之和的比成為列基數(shù))時提供了比較好的性能,B*樹索引是基于二叉樹的,由分支塊和葉塊組成.在樹結(jié)構(gòu)中,位于最底層的快成為葉塊,包含每個被索引列的值和行所對應的rowid.在葉節(jié)點的上面是分支塊,用來導航結(jié)構(gòu),包含了索引列(關鍵字)范圍和另一索引快的地址,如圖所示: (javaeye的圖片插入做的不夠好,插圖進來我覺得很好麻煩)





假設要查找索引中值為80的行,從索引樹的最上層入口開始,首先定位到大于等于50,然后往左找,找到第二個分支塊,定位到75―100,然后定位到葉塊,定位到葉塊,找到80所對應的rowid,然后根據(jù)rowid到數(shù)據(jù)塊讀取對應的數(shù)據(jù)。如果查詢條件是范圍選擇的,比如colume>20 and colume<80,那么會先定位到20的塊,然后再橫向查找到80的塊為止,不是每次都從入口進去重新定位的。
要說明的是,這種索引是用得最多的,基本上所有的數(shù)據(jù)庫系統(tǒng)都支持這種索引,它是索引里最主要最普遍的,它之所以稱為B*樹索引,更多是因為它的存儲結(jié)構(gòu)有著普遍的意義,很多索引都基于這種結(jié)構(gòu),當然sqlserver里沒有名為B*樹的索引,但是不妨礙我們以對B*樹索引的認識去理解sqlserver的索引,不是嗎?這是我為什么把它放在最前面的原因.

 

 

 



2:聚集索引 

 

      沒錯,這是sqlserver里很重要的一個索引.也叫群集索引。 聚集索引是相對于常規(guī)索引而言的,oracle也有類似的索引,不過叫聚簇索引,注意,雖然聚簇和聚集僅有一字之差,但是oracle的聚簇索引和sqlserver的聚集索引還是有很多的不同的,oracle的聚簇索引可以針對多表,根據(jù)多個表相同列的不同值,將相關數(shù)據(jù)聚集在周圍.sqlserver聚集索引也有類似的意思,但是只能針對單表.在oracle里,聚簇”是oralce內(nèi)部的一個對象,就像基本表,視圖,觸發(fā)器這些概念一樣. 聚簇索引就是對聚簇進行的索引,由于比較復雜,在此不詳細討論,但在sqlserver里,聚集索引直接作用在表上,因此不可以將二者混淆.反正不能等同來看就是了.

 
      舉個例子說明來說明sqlserver的聚集索引:我們的漢語字典的正文本身就是一個聚集索引。比如,我們要查“安”字,就會很自然地翻開字典的前幾頁,因為“安”的拼音是“an”,而按照拼音排序漢字的字典是以英文字母“a”開頭并以“z”結(jié)尾的,那么“安”字就自然地排在字典的前部。如果您翻完了所有以“a”開頭的部分仍然找不到這個字,那么就說明您的字典中沒有這個字;同樣的,如果查“張”字,那您也會將您的字典翻到最后部分,因為“張”的拼音是“zhang”。也就是說,字典的正文部分本身就是一個目錄,您不需要再去查其他目錄來找到您需要找的內(nèi)容。 我們把這種正文內(nèi)容本身就是一種按照一定規(guī)則排列的目錄稱為“聚集索引”。 聚集索引都是排好序的.


      如果您認識某個字,您可以快速地從自動中查到這個字。但您也可能會遇到您不認識的字,不知道它的發(fā)音,這時候,您就不能按照剛才的方法找到您要查的字,而需要去根據(jù)“偏旁部首”查到您要找的字,然后根據(jù)這個字后的頁碼直接翻到某頁來找到您要找的字。但您結(jié)合“部首目錄”和“檢字表”而查到的字的排序并不是真正的正文的排序方法,比如您查“張”字,我們可以看到在查部首之后的檢字表中“張”的頁碼是672頁,檢字表中“張”的上面是“馳”字,但頁碼卻是63頁,“張”的下面是“弩”字,頁面是390頁。很顯然,這些字并不是真正的分別位于“張”字的上下方,現(xiàn)在您看到的連續(xù)的“馳、張、弩”三字實際上就是他們在非聚集索引中的排序,是字典正文中的字在非聚集索引中的映射。我們可以通過這種方式來找到您所需要的字,但它需要兩個過程,先找到目錄中的結(jié)果,然后再翻到您所需要的頁碼。
      總而言之, 聚集索引就是使與被索引的值相關的行數(shù)據(jù)塊集中在一起,不是物理上的散列分布.這樣,首先縮小了掃描范圍,而且定位數(shù)據(jù)的時間短,可以想象一下查字典的時候,根據(jù)拼音查找漢字,找以”a”發(fā)音開頭的字,你只會在a字母里面找,如果a字母找完了,那么不管有沒有這個字,查找過程也就結(jié)束了。
非聚集索引也是B*樹結(jié)構(gòu),只不過每個索引值對應的不是行id,而是數(shù)據(jù)行本身,聚集索引會對表排序,就像字典一樣,它按照英文字母的順序排序的,所以在基于某個范圍搜索的時候,它的查詢效率是很高的,但同時我們也可以看到,它占據(jù)了更多的空間,在插入更新的時候,它會花多一點的時間維持自己的索引順序。每個表只能有一個聚集索引,這是當然的,因為每個表肯定只可能有一個全表排序的規(guī)則。



3:非聚集索引
      非聚集索引是一種典型的B*樹索引,每個葉塊只包含兩種數(shù)據(jù),一種是索引項,一種是該索引項所在行的行指針,當查詢的數(shù)據(jù)匹配該索引項數(shù)據(jù)的時候,將會取出對應的行指針,取得該行的數(shù)據(jù).如果要根據(jù)鍵值從大型 SQL Server 表提取具有良好選擇性的少數(shù)幾行,非聚集索引最有用。B*樹的底部或葉級包含組成該索引的列中的所有數(shù)據(jù)。當用非聚集索引檢索表中與鍵值匹配的信息時,將搜索整個索引 B 樹,直到在索引葉級找到一個與鍵值匹配的值。
在非聚集索引中,葉級節(jié)點僅包含參與索引的數(shù)據(jù)以及快速找到相關數(shù)據(jù)頁上其它行數(shù)據(jù)的指針。最糟糕的情況是,從非聚集索引中獲得的每一行都要求一個額外的不連續(xù)磁盤 I/O 才能檢索行數(shù)據(jù)。最好的情況是,所需要的行有許多都位于相同的數(shù)據(jù)頁,因此在提取每個數(shù)據(jù)頁時可檢索多行。如果是聚集索引,索引的葉級節(jié)點是表的實際數(shù)據(jù)行。因此,檢索表數(shù)據(jù)時不需要指針跳動?;诰奂饕姆秶鷴呙鑸?zhí)行情況很好,因為聚集索引的葉級(即表的所有行)在物理上按照組成聚集索引的列順序排列在磁盤上.



4:覆蓋索引
      覆蓋索引是非聚集索引的一個特例。覆蓋索引的定義是在選擇條件和 WHERE 謂詞上均滿足 SQL 查詢的所有列的基礎上建立的非聚集索引。覆蓋索引可以節(jié)省大量的 I/O,因此可極大地改善查詢的性能。但是有必要在新建索引(以及與它相關的 B 樹索引結(jié)構(gòu)維護)所需要的代價和覆蓋索引所帶來的 I/O 性能增益之間進行權(quán)衡。如果覆蓋索引對于 SQL Server 上經(jīng)常運行的查詢或查詢組極其有利,那么創(chuàng)建覆蓋索引是值得的。
覆蓋索引的示例


Select col1,col3 from table1 where col2 = 'value'.
Create index indexname1 on table1(col2,col1,col3).
本例中創(chuàng)建出來的索引“indexname1”是一個覆蓋索引,因為它包括 SELECT 語句和 WHERE 謂詞中的所有列。即在執(zhí)行此查詢期間,SQL Server 不需要訪問與 table1 相關的數(shù)據(jù)頁。SQL Server 使用索引 indexname1 可以獲得滿足查詢所需要的全部信息。在 SQL Server 已遍歷與 indexname1 相關的 B 樹,并找到 col2 等于“value”的索引關鍵字范圍,SQL Server 就知道它可以從覆蓋索引的葉級(底層)提取所有需要的數(shù)據(jù) (col1,col2,col3)。這從兩個方面改進了 I/O 性能:
    

      SQL Server 僅從索引頁而不是數(shù)據(jù)頁獲取所有需要的數(shù)據(jù),因此數(shù)據(jù)的壓縮率更高,使 SQL Server 可以節(jié)省磁盤 I/O 操作。
覆蓋索引按照 col2 將所有需要的數(shù)據(jù)以物理方式組織在磁盤上。使硬盤得以連續(xù)返回與 where 謂詞 (col2 = "value") 相關的所有索引行。從而為我們提供了更好的 I/O 性能。 總而言之,如果覆蓋索引中的所有列的字節(jié)數(shù)比該表中單行的字節(jié)數(shù)少,并且可以肯定將反復執(zhí)行使用此覆蓋索引的查詢,那么使用覆蓋索引是有意義的。

5:位圖索引
      這個不是sqlserver的索引,它是oracle的,所以請不要混淆。之所以提出來,是因為它不是B*樹結(jié)構(gòu)的索引。位圖索引相對于B*tree索引來說,它的存儲結(jié)構(gòu)是不一樣的,通常在B*tree索引中,在索引條目和行之間有一對一的關系.對于位圖索引,一個索引條目使用一個位圖同時指向許多行.這對于基本上只讀的低基數(shù)(數(shù)據(jù)只有很少的幾個截然不同的值)數(shù)據(jù)是合適的.比如說,一個person表,有個性別字段sex,Y代表男,N代表女,對于有幾百萬行數(shù)據(jù)的表來說, 位圖索引是一個非常好的選擇。它可以迅速的掃描出來,而不用象對B*樹索引那樣的查找。

 

 



3.2 有效的利用索引


      索引在數(shù)據(jù)庫的查詢優(yōu)化中起著至關重要的作用,一個數(shù)據(jù)庫索引的好與壞,其查詢性能相差很多倍,下面將談一下各種索引的使用場合和一些觀點。如何選擇索引可顯著影響所產(chǎn)生的磁盤 I/O,并因而影響查詢性能。在非聚集索引中,選擇性很重要,因為如果在只有少量唯一值的大型表上創(chuàng)建非聚集索引,使用非聚集索引將不會節(jié)省數(shù)據(jù)檢索中的 I/O。因為B*樹結(jié)構(gòu)的索引都注重一種比較性,這樣它可以快速的確定范圍,定位位置,例如,person表的性別字段,非男即女,不具有可比性,如果以它為非聚集索引,查詢的時候也只能一個個葉節(jié)點去比較。在這種情況下產(chǎn)生的 I/O 可能比對表進行連續(xù)掃描所產(chǎn)生的 I/O 多得多。比較適合非聚集索引的有發(fā)票編號、唯一的客戶編號、社會安全號碼和電話號碼,簡單來說,就是基于某種可比較的,有規(guī)律的數(shù)據(jù)。
創(chuàng)建聚集索引之前,應先了解數(shù)據(jù)是如何被訪問的。

 

考慮對具有以下特點的查詢使用聚集索引:


使用運算符(如 BETWEEN、>、>=、< 和 <=)返回一系列值。 使用聚集索引找到包含第一個值的行后,便可以確保包含后續(xù)索引值的行物理相鄰。例如,如果某個查詢在一系列銷售訂單號間檢索記錄,銷售單號列的聚集索引可   快速定位包含起始銷售訂單號的行,然后檢索表中所有連續(xù)的行,直到檢索到最后的銷售訂單號。
返回大型結(jié)果集。
使用 JOIN 子句;一般情況下,使用該子句的是外鍵列。
使用 ORDER BY 或 GROUP BY 子句。 
在 ORDER BY 或 GROUP BY 子句中指定的列的索引,可以使數(shù)據(jù)庫引擎 不必對數(shù)據(jù)進行排序,因為這些行已經(jīng)排序,這樣可以提高數(shù)據(jù)庫性能


一般情況下,定義聚集索引鍵時使用的列越少越好??紤]具有下列一個或多個屬性的列: 


 唯一或包含許多不重復的值
例如,雇員 ID 唯一地標識雇員。EmployeeID 列的聚集索引或 PRIMARY KEY 約束將改善基于雇員 ID 號搜索雇員信息的查詢的性能。另外,可對 LastName、FirstName、MiddleName 列創(chuàng)建聚集索引,因為經(jīng)常以這種方式分組和查詢雇員記錄,而且這些列的組合還可提供高區(qū)分度。


按順序被訪問
例如,id唯一地標識person表中的記錄,在其中指定順序搜索的查詢(如 WHERE ID BETWEEN 1000 and 2000)將從id的聚集索引受益。這是因為行將按該鍵列的排序順序存儲。


經(jīng)常用于對表中檢索到的數(shù)據(jù)進行排序。
按該列對表進行聚集(即物理排序)是一個好方法,它可以在每次查詢該列時節(jié)省排序操作的成本。
聚集索引不適用于具有下列屬性的列:


頻繁更改的列
這將導致整行移動,因為數(shù)據(jù)庫引擎 必須按物理順序保留行中的數(shù)據(jù)值。這一點要特別注意,因為在大容量事務處理系統(tǒng)中數(shù)據(jù)通常是可變的。


寬鍵
寬鍵是若干列或若干大型列的組合。所有非聚集索引將聚集索引中的鍵值用作查找鍵。為同一表定義的任何非聚集索引都將增大許多,這是因為非聚集索引項包含聚集鍵,同時也包含為此非聚集索引定義的鍵列。

 

 

 

3.3 談索引使用的誤區(qū)

      理論的目的是應用。雖然我們剛才列出了何時應使用聚集索引或非聚集索引,但在實踐中以上規(guī)則卻很容易被忽視或不能根據(jù)實際情況進行綜合分析。下面我們將根據(jù)在實踐中遇到的實際問題來談一下索引使用的誤區(qū)。

1:主鍵就是聚集索引
      這種想法我認為不是太合理,大多數(shù)情況下,主鍵上的聚集索引是對聚集索引的一種浪費。雖然SQL SERVER默認是在主鍵上建立聚集索引的。通常,我們會在每個表中都建立一個ID列,以區(qū)分每條數(shù)據(jù),并且這個ID列是自動增大的,步長一般為1。此時,如果我們將這個列設為主鍵,SQL SERVER會將此列默認為聚集索引。這樣做有好處,就是可以讓您的數(shù)據(jù)在數(shù)據(jù)庫中按照ID進行物理排序,但我認為這樣做意義不大。因為在很多情況下,由于主鍵的唯一性,對id或者主鍵進行范圍掃描 是比較少的。顯而易見,聚集索引的優(yōu)勢是很明顯的,而每個表中只能有一個聚集索引的規(guī)則,這使得聚集索引變得更加珍貴。 從我們前面談到的聚集索引的定義我們可以看出,使用聚集索引的最大好處就是能夠根據(jù)查詢要求,迅速縮小查詢范圍,避免全表掃描。
在實際應用中,因為ID號是自動生成的,我們并不知道每條記錄的ID號,所以我們很難在實踐中用ID號來進行查詢。這就使讓ID號這個主鍵作為聚集索引成為一種資源浪費。其次,讓每個ID號都不同的字段作為聚集索引也不符合“大數(shù)目的不同值情況下不應建立聚合索引”規(guī)則;當然,這種情況只是針對用戶經(jīng)常修改記錄內(nèi)容,特別是索引項的時候會負作用,但對于查詢速度并沒有影響。 如果您的聚集索引盲目地建在ID這個主鍵上時,查詢速度不一定會提高的,即使你在其他字段上建立非聚集索引。下面我們就來看一下在200萬條數(shù)據(jù)量的情況下各種查詢的速度表現(xiàn):

(1)全表掃描
只在主鍵上建立聚集索引:
Select id,name,dept,emdate from person
用時:20546毫秒(即:21秒)
不在主鍵上建立聚集索引,只建普通索引
Select id,name,dept,emdate from person
用時:17923毫秒(即:18秒)
以上查詢執(zhí)行的實際上索引不會發(fā)揮作用,因為提取的是全部數(shù)據(jù)。聚集索引在這里會耗費更多的資源,所以會看到,不建立聚集索引比建立聚集索引還要快


(2):按日期進行過濾(用到索引)
在主鍵上建立聚集索引,在emdate上建立非聚集索引:
select id,name,dept,emdate from person where emdate>dateadd(day,+1,getdate())
用時:12376毫秒(12秒)

在主鍵上建立聚集索引,在emdate上沒有索引:
select id,name,dept,emdate from person where emdate>dateadd(day,+1,getdate())
用時:21296毫秒(21秒)

在主鍵上建立非聚集索引,在emdate上建立非聚集索引:
select id,name,dept,emdate from person where emdate>dateadd(day,+1,getdate())
用時:11590毫秒(12秒)

在主鍵上建立非聚集索引,在emdate上建立聚集索引:
select id,name,dept,emdate from person where emdate>dateadd(day,+1,getdate())
andemdate<dateadd(day,+3,getdate())
用時:5233毫秒(5秒)

雖然每條語句提取出來的都是30萬條數(shù)據(jù),各種情況的差異卻是比較大的,特別是將聚集索引建立在日期列時的差異。事實上,如果您的數(shù)據(jù)庫真的有幾千萬條記錄的話,差距會更明顯。


2:只要建立索引就能顯著提高查詢速度
      這個想法是錯誤的。事實上,我們可以發(fā)現(xiàn)上面的例子中,上面按日期過濾的語句完全相同,且建立索引的字段也相同,但查詢速度卻有著非常大的差別。所以,并非是在任何字段上簡單地建立索引就能提高查詢速度。索引的建立,會帶來更多的系統(tǒng)開銷,因為系統(tǒng)要耗費資源去維護它 ,如果建立了沒有用到的索引,不適當?shù)乃饕?,過多的索引,反而會導致查詢性能下降??傊饕慕?,要看表的結(jié)構(gòu),數(shù)據(jù)的分布,還有你要用到哪些數(shù)據(jù),如果把索引建立在你根本不需要的數(shù)據(jù)列上,是根本不會發(fā)揮作用的。

3:把所有需要提高查詢速度的字段都加進聚集索引,以提高查詢速度
      這個不一定正確。上面已經(jīng)談到。假設現(xiàn)在查詢要用到用戶名和日期這兩個字段,我們可以把他們合并起來,建立一個復合索引(compound index)。 很多人認為只要把任何字段加進聚集索引,就能提高查詢速度,也有人感到迷惑:如果把復合的聚集索引字段分開查詢,那么查詢速度會減慢嗎?帶著這個問題,我們來看一下以下的查詢速度(結(jié)果集都是25萬條):(日期列emdate首先排在復合聚集索引的起始列,用戶名name排在后列)

select id,name,dept,emdate from person where emdate>'2007-06-01'
查詢速度:1664毫秒
select id,name,dept,emdate from person
where emdate>'2007-06-01' and name=’王小雪’
查詢速度:1640毫秒
select gid,fariqi,neibuyonghu,title from person
where name='王小雪'
查詢速度:5920毫秒
從以上試驗中,我們可以看到如果僅用聚集索引的起始列作為查詢條件和同時用到復合聚集索引的全部列的查詢速度是幾乎一樣的,而如果僅用復合聚集索引的非起始列作為查詢條件的話,這個索引是不起任何作用的。當然,語句1、2的查詢速度一樣是因為查詢的條目數(shù)一樣,如果復合索引的所有列都用上,而且查詢結(jié)果少的話,這樣就會形成“索引覆蓋”,因而性能可以達到最優(yōu)。同時,請記?。簾o論您是否經(jīng)常使用聚合索引的其他列,但其前導列一定要是使用最頻繁的列。



3.4 其他索引經(jīng)驗總結(jié)
1:用聚合索引比用不是聚合索引的主鍵速度快
下面是實例語句:(都是提取25萬條數(shù)據(jù))
select id,name,dept,emdate from person where emdate='2007-06-04'
使用時間:906毫秒

select id,name,dept,emdate from person where id<=100000
使用時間:1153毫秒
這里,用聚合索引比用不是聚合索引的主鍵速度略快一些。


2:用聚合索引比用一般的主鍵作order by時速度快,特別是小數(shù)據(jù)量時
select id,name,dept,emdate from person order by emdate
用時:17856 (約18秒)

select id,name,dept,emdate from person order by id
用時:44046 (約45秒)

這里可以看到,用聚集索引比用一般的主鍵作order by時,速度幾乎快了2.5倍。事實上,有的資料說小數(shù)據(jù)量情況下,用聚集索引排序列比非聚集索引作為排序列快,10萬以上,則二者的速度差別不明顯。但據(jù)當前200萬條數(shù)據(jù)情況來看,在大數(shù)據(jù)量的情況下,這個結(jié)論依然成立。

3:使用聚合索引內(nèi)的時間段,搜索時間會按數(shù)據(jù)占整個數(shù)據(jù)表的百分比
比例減少,而無論聚合索引使用了多少個
select id,name,dept,emdate from person where
emdate='2007-06-04 00:00:00.000'
用時:1123毫秒(提取10萬條)

select id,name,dept,emdate from person where
emdate='2007-06-04 00:00:00.000'
用時:1843毫秒(提取20萬條)

select id,name,dept,emdate from person where
emdate='2007-06-09 00:00:00.000'
用時:4500毫秒(提取45萬條)

從以上統(tǒng)計的數(shù)據(jù)看來,這個規(guī)律基本上是正確的



其他注意事項
    “水可載舟,亦可覆舟”,索引也一樣。索引有助于提高檢索性能,但過多或不當?shù)乃饕矔е孪到y(tǒng)低效。因為用戶在表中每加進一個索引,數(shù)據(jù)庫就要做更多的工作。過多的索引甚至會導致索引碎片。所以說,我們要建立一個“適當”的索引體系,特別是對聚合索引的創(chuàng)建,更應精益求精,以使您的數(shù)據(jù)庫能得到高性能的發(fā)揮。在實際的開發(fā)中,會遇到很多意想不到的情況,最好是多測試一些方案,找出哪種方案效率最高、最為有效。

 

 

 



4:SQL語句改善
       一個sql語句大約要經(jīng)過三個階段,編譯優(yōu)化,執(zhí)行,取值,而編譯階段,而第一階段大部分情況下都要花掉60%的時間,所以綁定變量是很重要的,sqlserver和oracle都有緩存區(qū),存放最近使用的sql語句,當有一條sql語句到達數(shù)據(jù)庫服務器時,數(shù)據(jù)庫會首先搜索緩存區(qū),看它是否存在可以重用的sql語句,如果存在,則無需編譯優(yōu)化,因為緩存區(qū)的sql語句都是編譯優(yōu)化好了的,可以直接執(zhí)行,節(jié)省相當多的時間。如果沒有發(fā)現(xiàn)該語句,則必須要完全經(jīng)歷語句編譯分析,優(yōu)化計劃,安全檢查等過程,這不僅耗費了大量的cpu功率,而且還在相當長的一段時間內(nèi)鎖住了一部分數(shù)據(jù)庫緩存,這樣執(zhí)行sql語句的人越多,等待的時間越長,系統(tǒng)的性能會大幅度的下降。


很多人不知道SQL語句在SQL SERVER中是如何執(zhí)行的,他們擔心自己所寫的SQL語句會被SQL SERVER誤解。比如:
select id,name,dept,emdate from person
where name='王小雪' and id<100000 用時:1220毫秒
和執(zhí)行:
select * from table1 where id< 100000 and name='王小雪' 用時:1173毫秒
一些人不知道以上兩條語句的執(zhí)行效率是否一樣,因為如果簡單的從語句先后上看,這兩個語句的確是不一樣,如果id是一個聚合索引,那么后一句僅僅從表的100000條以內(nèi)的記錄中查找就行了;而前一句則要先從全表中查找看有幾個name='王小雪'的,而后再根據(jù)限制條件條件id<100000來提出查詢結(jié)果。事實上,這樣的擔心是不必要的。SQL SERVER中有一個“查詢分析優(yōu)化器”,它可以計算出where子句中的搜索條件并確定哪個索引能縮小表掃描的搜索空間,也就是說,它能實現(xiàn)自動優(yōu)化。

 


      雖然查詢優(yōu)化器可以根據(jù)where子句自動的進行查詢優(yōu)化,但大家仍然有必要了解一下“查詢優(yōu)化器”的工作原理,如非這樣,有時查詢優(yōu)化器就會不按照您的本意進行快速查詢。 在查詢分析階段,查詢優(yōu)化器查看查詢的每個階段并決定限制需要掃描的數(shù)據(jù)量是否有用。如果一個階段可以被用作一個掃描參數(shù)(SARG),那么就稱之為可優(yōu)化的,并且可以利用索引快速獲得所需數(shù)據(jù)。 SARG的定義:用于限制搜索的一個操作,因為它通常是指一個特定的匹配,一個值得范圍內(nèi)的匹配或者兩個以上條件的AND連接。形式如下:
列名 操作符 <常數(shù) 或 變量> 或 <常數(shù) 或 變量> 操作符列名
列名可以出現(xiàn)在操作符的一邊,而常數(shù)或變量出現(xiàn)在操作符的另一邊。如:
Name=’張三’ ,價格>5000 ,5000<價格 ,Name=’張三’ and 價格>5000
如果一個表達式不能滿足SARG的形式,那它就無法限制搜索的范圍了,也就是SQL SERVER必須對每一行都判斷它是否滿足WHERE子句中的所有條件。所以一個索引對于不滿足SARG形式的表達式來說是無用的。
介紹完SARG后,我們來總結(jié)一下使用SARG以及在實踐中遇到的和某些資料上結(jié)論不同的經(jīng)驗:

1:Like語句是否屬于SARG取決于所使用的通配符的類型
如:name like ‘王%’ ,這就屬于SARG
而:name like ‘%小雪’,就不屬于SARG。
原因是通配符%在字符串的開通使得索引無法使用。 如以下查詢
沒有對name進行索引
select id,name,dept,emdate from person where name like '%小雪'
用時 3654毫秒
對name進行非聚集索引
select id,name,dept,emdate from person where name like '%小雪'
用時 3673毫秒
對name進行聚集索引
select id,name,dept,emdate from person where name like '%小雪'
用時 3673毫秒
由以上數(shù)據(jù)可以看到,將匹配符號放在被查詢字段的前面,索引根本就不會發(fā)生作用,所以這也是要注意的地方,如果不會用到,最好少用

2:or 是否會引起全表掃描
有很多資料上說or會引起全表掃描。
如name=’王小雪’ and emdate>’2007-01-10’不會全表掃描,而
name=’王小雪’ or emdate>’2007-01-10’則會,但是據(jù)我觀察,情況不是這樣的.對于這樣的一個sql語句select id,name,dept,emdate from person where name='王小雪' or emdate>'2007-06-08',我們可以看sqlserver對于它們的執(zhí)行計劃

在有聚集索引的情況下(無論聚集索引建在哪些字段上)


沒有聚集索引但是主鍵索引的情況下




沒有任何索引的情況下




由上可以得出結(jié)論,在用到or的時候,如果有聚集索引,就不會引起全表掃描,沒有聚集索引,就會引起全表掃描,所以說,只要用or就會引起全表掃描是片面的,不正確的。


3:非操作符、函數(shù)引起的不滿足SARG形式的語句 

 

 

 

      不滿足SARG形式的語句最典型的情況就是包括非操作符的語句,如:NOT、!=、<>、!<、!>、NOT EXISTS、NOT IN、NOT LIKE等,另外還有函數(shù)。下面就是幾個不滿足SARG形式的例子:
ABS(價格)<5000 ,Name like ‘%三’ ,有些表達式,如: WHERE 價格*2>5000 ,SQL SERVER也會認為是SARG,SQL SERVER會將此式轉(zhuǎn)化為: WHERE 價格>2500/2 .但不推薦這樣使用,因為有時SQL SERVER不能保證這種轉(zhuǎn)化與原始表達式是完全等價的。

4:IN 的作用是否相當與OR
看下面的查詢情況。
有聚集索引
select id,name,dept,emdate from person where name in('王小雪','聶海')
所花時間:8936ms,
select id,name,dept,emdate from person where name='王小雪' or name='聶海'
所花時間:5390ms,

沒有聚集索引
select id,name,dept,emdate from person where name in('王小雪','聶海')
所花時間:5310ms,
select id,name,dept,emdate from person where name='王小雪' or name='聶海'
所花時間:5326ms,

可見,or 比 in速度快,因為作了聚集索引,所以它們都沒有執(zhí)行table scan,不過因為聚集索引作用在日期字段emdate上,所以雖然查詢使用了聚集索引,但并不意味著比全表掃描快,其實使用作用在emdate上的聚集索引查詢,在某種意義上來說,也是一種全表掃描,只不過數(shù)據(jù)的掃描順序不同而已,在這種情況下,甚至沒有聚集索引反而更快

5:exists 和 in 的執(zhí)行效率是一樣的
     很多資料上都顯示說,exists要比in的執(zhí)行效率要高,同時應盡可能的用not exists來代替not in。但事實上,我試驗了一下,發(fā)現(xiàn)二者無論是前面帶不帶not,二者之間的執(zhí)行效率都是一樣的。因為涉及子查詢,我試驗這次用SQL SERVER自帶的pubs數(shù)據(jù)庫。運行前我們可以把SQL SERVER的statistics I/O狀態(tài)打開。 語法為:set statistics io on, 要查看語句的執(zhí)行過程,打開查詢分析器的消息欄就可以看到,但是在查詢語句之前要加上set statistics io on
(1)select title,price from titles where title_id in (select title_id from sales where qty>30)
該句的執(zhí)行結(jié)果為:
表 'sales'。掃描計數(shù) 18,邏輯讀 56 次,物理讀 0 次,預讀 0 次。
表 'titles'。掃描計數(shù) 1,邏輯讀 2 次,物理讀 0 次,預讀 0 次。

(2)select title,price from titles where exists (select * from sales where sales.title_id=titles.title_id and qty>30)
第二句的執(zhí)行結(jié)果為:
表 'sales'。掃描計數(shù) 18,邏輯讀 56 次,物理讀 0 次,預讀 0 次。
表 'titles'。掃描計數(shù) 1,邏輯讀 2 次,物理讀 0 次,預讀 0 次。

我們從此可以看到用exists和用in的執(zhí)行效率是一樣的。

6:用函數(shù)charindex()和前面加通配符%的LIKE執(zhí)行效率一樣
      前面,我們談到,如果在LIKE前面加上通配符%,那么將會引起全表掃描,所以其執(zhí)行效率是低下的。但有的資料介紹說,用函數(shù)charindex()來代替LIKE速度會有大的提升,但據(jù)我測試,發(fā)現(xiàn)這種說明也是錯誤的:
select id,name,dept,emdate from person where charindex('小雪',name)>0
用時:4010ms
掃描計數(shù) 1,邏輯讀 29905 次,物理讀 0 次,預讀 0 次。

select id,name,dept,emdate from person where name like '%小雪'
用時:4123ms
掃描計數(shù) 1,邏輯讀 29905 次,物理讀 0 次,預讀 0 次。

7:union并不絕對比or的執(zhí)行效率高
      很多資料都推薦用union來代替or。事實證明,這種說法對于大部分都是適用的。
(1):select id,name,dept,emdate from person where name='王小雪' or emdate>'2007-06-04'
用時:85626ms。掃描計數(shù) 1,邏輯讀 129905 次,物理讀 0 次,預讀 0 次。次。
(2):select id,name,dept,emdate from person where name='王小雪'
union
select id,name,dept,emdate from person where emdate>'2007-06-04'
用時:17373ms。掃描計數(shù) 2,邏輯讀 59810 次,物理讀 0 次,預讀 0 次。
看來,用union在通常情況下比用or的效率要高的多。


5:sqlserver的分區(qū)
      對于一些超大型的表,分區(qū)是非常有用的。分區(qū)是一種邏輯概念,和oracle的分區(qū)概念是一樣的.在通常情況下,一個表就是一個整體,當發(fā)生數(shù)據(jù)訪問的時候,也是對整個表或整個表的索引進行訪問,所謂分區(qū),通俗點講,就是把表按一定的規(guī)律劃分成更小的邏輯單位,當發(fā)生訪問的時候,不以表為單位進行訪問,而先在表的基礎上,判斷數(shù)據(jù)在哪個分區(qū),然后對特定的分區(qū)進行訪問.正確的分區(qū)有利于提高查詢性能.例如,有一個非常大的表,存儲了一些銷售記錄,現(xiàn)在查詢總是按銷售季度來執(zhí)行這個查詢----每個銷售季度包含幾十萬個記錄,通常你只是要查詢這個數(shù)據(jù)集的一個相當小的數(shù)據(jù),但是給予銷售季度的檢索卻的確是不太可行的.這個索引可能指向無數(shù)個記錄,而以這種方式執(zhí)行索引范圍掃描是可怕的.為了處理許多查詢?nèi)蝿?系統(tǒng)需要執(zhí)行全表掃描,但是結(jié)果卻必須掃描幾百萬個記錄,其中絕大部分不使用我們的查詢?nèi)蝿?使用智能分區(qū)方案,就可以按季度隔離數(shù)據(jù).這樣當我們?yōu)槿我庵付ǖ募径热ゲ樵償?shù)據(jù)時,結(jié)果將只是掃描那個季度的數(shù)據(jù).這是所有可能的解決方案種最好的方案.下面將介紹sqlserver的分區(qū)使用.


      分區(qū)是比較復雜的,以分區(qū)的對象來分類的話,則分為兩種,表分區(qū)和索引分區(qū)。
表分區(qū)主要指的是范圍分區(qū),(貌似比較單一,oracle里有散列分區(qū)等等,不過在sqlserver里我目前還沒有看到).就這么說可能不清不楚,下面將以我們已經(jīng)建立好的ipanel數(shù)據(jù)庫為例,對person表進行按日期分區(qū),假設ipanel每個月都要進出幾十萬人,然后HR每月還要作很多的統(tǒng)計吧。下面一步一步來,common?

創(chuàng)建文件組
各種數(shù)據(jù)最終是存儲在數(shù)據(jù)文件里,在實際應用中,表的分區(qū)都會分布在多個數(shù)據(jù)文件中,這樣以便獲得更好的 I/O 平衡,對于文件,是以文件組為單位進行管理,文件組相當于目錄,數(shù)據(jù)文件就相當于目錄里的文件。為數(shù)據(jù)庫添加文件組,這個文件組分布存儲person表的數(shù)據(jù):
ALTER DATABASE ipanel ADD FILEGROUP [person_fg]
現(xiàn)在為ipanel數(shù)據(jù)庫創(chuàng)建了一個名為person_fg的文件組。下面為該文件組添加數(shù)據(jù)文件。

添加數(shù)據(jù)文件
ALTER DATABASE ipanel
ADD FILE
(NAME = N'person001',
FILENAME = N'C:\ipanel\person001.ndf',
SIZE = 5MB,
MAXSIZE = 100MB,
FILEGROWTH = 5MB)
TO FILEGROUP [person_fg]
如上,為文件組添加了一個數(shù)據(jù)文件

創(chuàng)建分區(qū)函數(shù)
既然分區(qū),那么就應該有一個分區(qū)的標準,就是說數(shù)據(jù)將以什么標準來分區(qū),分區(qū)函數(shù)就是做這件事情的,它定義數(shù)據(jù)劃分的標準,對表進行邏輯上的劃分。
CREATE PARTITION FUNCTION personRangePFN(datetime)
AS
RANGE LEFT FOR VALUES ('20030930',
'20050930',
'20070930',
'20090930')
上面的分區(qū)函數(shù)創(chuàng)建了5個分區(qū),并且定義了分區(qū)列的數(shù)據(jù)類型為datetime,因為分區(qū)的標準要建在表的某一列上,在此定義,分區(qū)列必須是日期時間型。RANGE LEFT表示范圍分區(qū),LEFT所在的選項有兩個:LEFT,RIGHT.分區(qū)標識著數(shù)據(jù)的上界和下界。如當前選項是LEFT,則表示:
分區(qū)1:<=20030930
分區(qū)2:>20030930,<=20050930
分區(qū)3:>20050930,<=20070930
分區(qū)4:>20070930,<=20090930
分區(qū)5:>20030930
如果當前選項是RIGHT,則表示:
分區(qū)1:<20030930
分區(qū)2:>=20030930,<20050930
分區(qū)3:>=20050930,<20070930
分區(qū)4:>=20070930,<20090930
分區(qū)5:>=20030930


創(chuàng)建分區(qū)架構(gòu)
創(chuàng)建分區(qū)函數(shù)后,必須將其與分區(qū)架構(gòu)相關聯(lián),以便將分區(qū)定向至特定的文件組。定義分區(qū)架構(gòu)時,即使多個分區(qū)位于同一個文件組中,也必須為每個分區(qū)指定一個文件組。對于前面創(chuàng)建的范圍分區(qū) (personRangePFN),存在五個分區(qū);最后一個空分區(qū)將在 PRIMARY 文件組中創(chuàng)建。因為此分區(qū)永遠不包含數(shù)據(jù),所以不需要指定特殊的位置
CREATE PARTITION SCHEME PersonEmdateScheme
AS
PARTITION personRangePFN
TO ([person001], [person002], [person003], [person004], [PRIMARY])



創(chuàng)建分區(qū)表
      定義分區(qū)函數(shù)(邏輯結(jié)構(gòu))和分區(qū)架構(gòu)(物理結(jié)構(gòu))后,即可創(chuàng)建表來利用它們。表定義應使用的架構(gòu),而架構(gòu)又定義函數(shù)。要將這三者結(jié)合起來,必須指定應該應用分區(qū)函數(shù)的列。范圍分區(qū)始終只映射到表中的一列,此列應與分區(qū)函數(shù)中定義的邊界條件的數(shù)據(jù)類型相匹配。另外,如果表應明確限制數(shù)據(jù)集(而不是從負無窮大到正無窮大),則還應添加 CHECK 約束。

CREATE TABLE [dbo].[person] (
[id] [bigint] NOT NULL , --記錄的id
[name] [varchar] (10) COLLATE Chinese_PRC_CI_AS NULL ,--姓名
[age] [int] NULL ,--年齡
[addr] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,--地址
[sex] [char] (10) COLLATE Chinese_PRC_CI_AS NULL ,--性別
[dept] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,--部門
[pos] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,--郵編
[tel] [char] (15) COLLATE Chinese_PRC_CI_AS NULL ,--電話
[fax] [char] (15) COLLATE Chinese_PRC_CI_AS NULL ,--傳真
[emdate] [datetime] NULL --入職日期
)
On PersonEmdateScheme (emdate)
如果要限制的emdate的值的范圍,則必須給它加上約束,如只允許emdate的值從2002年9月1日到2010年9月1日,
則將[emdate] [datetime] NULL 改為

[emdate] [datetime] NULL
CONSTRAINT personRangeYear
CHECK ([emdate] >= '20020901'
AND [emdate] <= '20100901 11:59:59.997')

分區(qū)總結(jié)
     到此,對于分區(qū)表person已經(jīng)設置完畢,person的數(shù)據(jù)會根據(jù)emdate的值分布到幾個不同的數(shù)據(jù)文件里,在查詢的時候,系統(tǒng)會首先判斷emdate的值,看它在哪個分區(qū),然后只進入該分區(qū)查找數(shù)據(jù),這對于超大規(guī)模的系統(tǒng)來說,是很有用的,如果一個表有幾千萬上億的數(shù)據(jù),即使是索引掃描也是一個很費時的過程,不要忘記,索引也就像相當于簡化了的表。對于索引,sqlserver里有索引分區(qū),如果索引分區(qū)和表分區(qū)對齊的話,就是說和表一樣使用了相同的分區(qū)函數(shù)和相同的分區(qū)架構(gòu),那么對于索引的查找,就不是對整個索引的查找了,而是先判斷在哪個索引分區(qū),然后再取查找該索引值,然后找到數(shù)據(jù),這樣就會節(jié)省很多時間。分區(qū)還有一個好處就是,對于一些數(shù)據(jù)可以更好的進行管理,比如說,定義了2006年度的銷售數(shù)據(jù)存儲在對應的分區(qū)area6,而area6對應的數(shù)據(jù)文件是sale006.ndf,到2007年的時候,一般情況下,可能不用06年的數(shù)據(jù),按照分區(qū)的理論,它也不會訪問06年的數(shù)據(jù)所在的區(qū)域。
分區(qū)的應用是比較復雜的,上面只是介紹了其中一部分,其他還有索引分區(qū),分區(qū)合并,分區(qū)移出等比較多的的東西。在oracle里,分區(qū)的概念是比較多的,包括對索引的分區(qū)都會有很多介紹,如散列分區(qū),混合分區(qū),局部索引,全局索引,原理上是差不多的。在此談分區(qū)只是一個拋磚引玉的過程,如果對sqlserver分區(qū)想更深入了解的話,可以看看msdn,有中文的,不過翻譯得很爛。


6:后記
      我以前看到過很多項目,數(shù)據(jù)庫系統(tǒng)只是被純粹的當作了一個存儲數(shù)據(jù)的地方,建完表能增刪改查就萬事大吉了,有的連索引都沒有,對于數(shù)據(jù)庫的建立也很不嚴謹,更談不上管理,雖然很多人認為數(shù)據(jù)庫的管理是DBA的事情,但是我想作為一個技術(shù)人員,加深對數(shù)據(jù)庫的了解是絕對沒有壞處的,開發(fā)大型的系統(tǒng),數(shù)據(jù)庫肯定是非常重要的。想從一個普通編程人員往上突破,你必然不能將眼光僅僅局限在某一個編程技術(shù)上,比如,你搞java開發(fā),或許你對java的很多東西都很熟悉了,編寫某個復雜的模塊,或許你毫不費力。但是當你是一個項目經(jīng)理或是一個架構(gòu)師的時候,面對一個復雜且用戶量大,要求苛刻的系統(tǒng),你是否覺得會力不從心?是否會覺得你所熟悉的java技術(shù),鉆研的設計模式,奇怪的語法,似乎都變成奇技淫巧,不成大器了?做web系統(tǒng)或企業(yè)應用,再往上走,基本沒有語言的差別,高層次人才的競爭必然在于對整體系統(tǒng)的把握,包括行業(yè)經(jīng)驗,網(wǎng)絡,存儲,系統(tǒng)架構(gòu)(不要認為是SSH,我說的不是軟件系統(tǒng)的編碼結(jié)構(gòu))。

    

     如果想深入學習一門數(shù)據(jù)庫的話,我建議大家從oracle開始學,因為sqlserver作了很多封裝,而oracle更為復雜,是的,雖然它概念很多,比較復雜,但是卻有助你了解更多的數(shù)據(jù)庫細節(jié),在很多方面,大部分的數(shù)據(jù)庫系統(tǒng)都是相同的,oracle學好再來學其他的數(shù)據(jù)庫,上手就非常容易,如果你會寫PL/SQL程序,那有什么理由不會寫TRANACT-SQL的數(shù)據(jù)庫程序呢,語法只是一些細微的差別,而很多的概念卻是相同的。

 

 

 

我了大家看得清楚,我編輯格式好累啊,終于搞完了,順便說一下,javaeye的編輯器有待改進啊。

本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
十步優(yōu)化SQL Server中的數(shù)據(jù)訪問
數(shù)據(jù)庫部分(MySql)_4
sql 非聚集索引使用INCLUDE
SQL數(shù)據(jù)庫面試題
海量數(shù)據(jù)庫的查詢優(yōu)化及分頁算法方案
大數(shù)據(jù)量高并發(fā)的數(shù)據(jù)庫優(yōu)化
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服