分区表理论解析(上):SQL Server 2k52k8系列(一)
生活随笔
收集整理的這篇文章主要介紹了
分区表理论解析(上):SQL Server 2k52k8系列(一)
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
在談?wù)摲謪^(qū)表這個(gè)話題之前,先和大家分享一個(gè)案例:<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> 2008年秋天的某天,我的團(tuán)隊(duì)接到成都市XX局一個(gè)SQL調(diào)優(yōu)的ESS單子。客戶反映查詢統(tǒng)計(jì)一次各地市局上報(bào)的數(shù)據(jù)匯總,需要6到15秒才能獲得真正想要的數(shù)據(jù),當(dāng)我和銷(xiāo)售人員趕到客戶數(shù)據(jù)中心現(xiàn)場(chǎng)后,發(fā)現(xiàn)里面布置了很多柜式服務(wù)器,每臺(tái)服務(wù)器都是8核<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />16G內(nèi)存。和相關(guān)技術(shù)負(fù)責(zé)人溝通以及演示業(yè)務(wù)系統(tǒng)之后,可以肯定不是服務(wù)器性能的問(wèn)題,我詳細(xì)分析了他們的數(shù)據(jù)庫(kù),統(tǒng)計(jì)慢的幾張表往往一周的上報(bào)數(shù)據(jù)便會(huì)增加1百多萬(wàn)行,導(dǎo)致他們這個(gè)系統(tǒng)剛上線沒(méi)多久,某些表產(chǎn)生的數(shù)據(jù)已經(jīng)在2000萬(wàn)行以上,最終我提出了優(yōu)化方案,業(yè)務(wù)邏輯層采用存儲(chǔ)過(guò)程代替普通的SQL語(yǔ)句,并啟用相關(guān)開(kāi)發(fā)平臺(tái)的緩存技術(shù);數(shù)據(jù)庫(kù)系統(tǒng)中采用增強(qiáng)索引和規(guī)劃分區(qū)表進(jìn)行優(yōu)化,最終問(wèn)題解決。 事實(shí)上數(shù)據(jù)庫(kù)性能優(yōu)化是每個(gè)優(yōu)秀的數(shù)據(jù)庫(kù)工程師必須具備的素質(zhì)之一,而這一節(jié)討論的分區(qū)表便是性能調(diào)優(yōu)的一種技術(shù)。在企業(yè)級(jí)應(yīng)用系統(tǒng)中,一個(gè)表存儲(chǔ)2千萬(wàn)行的數(shù)據(jù)很常見(jiàn),不可預(yù)期的數(shù)據(jù)也會(huì)在逐漸增長(zhǎng),所以數(shù)千萬(wàn)級(jí)別的表DBA會(huì)常常碰到,而TB級(jí)別的數(shù)據(jù)最終也在所難免,因此了解和掌握性能調(diào)優(yōu)的18般兵器非常重要。
當(dāng)然我們也可以根據(jù)月份分區(qū),而分區(qū)依據(jù)列支持的數(shù)據(jù)類(lèi)型非常多,參照項(xiàng)目的實(shí)際情況選擇最能表示分區(qū)的列類(lèi)型。 接分區(qū)表理論解析(下)
?
我計(jì)劃用三篇博文介紹分區(qū)表這個(gè)主題,分別為: 1,??? 分區(qū)表理論解析 2,??? 實(shí)戰(zhàn)分區(qū)表 3,??? 分區(qū)表前傳 ? <?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />?
大凡在應(yīng)用系統(tǒng)和數(shù)據(jù)庫(kù)系統(tǒng)中行走江湖多年的朋友,都會(huì)面臨數(shù)據(jù)統(tǒng)計(jì)、分析以及歸檔的問(wèn)題,企業(yè)信息化進(jìn)程加速了各種數(shù)據(jù)的極具增長(zhǎng),商務(wù)智能(BI)的出現(xiàn)和實(shí)施著實(shí)給信息工作者和決策者帶來(lái)了絕妙的體驗(yàn),但從 OLTP 向 OLAP 系統(tǒng)加載數(shù)據(jù)是很頭疼的事,常常需要數(shù)分鐘或數(shù)小時(shí),解決這一問(wèn)題的技術(shù)之一便是分區(qū)表,一旦實(shí)施了分區(qū)表,這樣的操作往往只需幾秒鐘,太讓人興奮了。而大型表或索引經(jīng)過(guò)分區(qū)后更容易進(jìn)行管理,因?yàn)檫@樣可以快速高效地管理和訪問(wèn)數(shù)據(jù)子集,同時(shí)維護(hù)數(shù)據(jù)集合的完整性。分區(qū)表的數(shù)據(jù)分布于一個(gè)數(shù)據(jù)庫(kù)中的多個(gè)文件組單元中,數(shù)據(jù)是按水平方式分區(qū)的(數(shù)據(jù)分區(qū)的多種方式會(huì)在分區(qū)表前傳中闡述),因此一個(gè)表的某些行映射到某個(gè)分區(qū),而另外一些行映射到另外某個(gè)分區(qū),以此類(lèi)推。當(dāng)對(duì)數(shù)據(jù)進(jìn)行查詢或更新時(shí),表將被視為單個(gè)邏輯實(shí)體,所以在數(shù)據(jù)訪問(wèn)層你會(huì)感覺(jué)和訪問(wèn)普通表一樣,而好處就在于可以查詢想要的某個(gè)分區(qū),而不必掃描整個(gè)表。有一點(diǎn)必須明白,單個(gè)表的所有分區(qū)都必須位于同一個(gè)數(shù)據(jù)庫(kù)中。 分區(qū)表支持和標(biāo)準(zhǔn)表相關(guān)的所有屬性和功能,包括約束、默認(rèn)值、標(biāo)識(shí)和時(shí)間戳值以及觸發(fā)器等。決定是否實(shí)現(xiàn)分區(qū)主要取決于表當(dāng)前的大小或?qū)?lái)的大小以及對(duì)表執(zhí)行查詢和維護(hù)操作的完善程度。 通常,如果某個(gè)大型表同時(shí)滿足下列兩個(gè)條件,則可能適于進(jìn)行分區(qū): 1,該表包含或?qū)远喾N不同方式使用的大量數(shù)據(jù) 2,維護(hù)開(kāi)銷(xiāo)超過(guò)了預(yù)定義的維護(hù)期 例如,如果對(duì)當(dāng)前年份或當(dāng)前月份的數(shù)據(jù)主要執(zhí)行 SELECT 、INSERT、UPDATE 和 DELETE 操作,而對(duì)以前年份或以前月份的數(shù)據(jù)主要執(zhí)行 SELECT 查詢,則如果按年份或月份對(duì)表進(jìn)行分區(qū),表的管理要容易些,因?yàn)榇藭r(shí)對(duì)表的維護(hù)操作只針對(duì)一個(gè)數(shù)據(jù)子集。如果該表沒(méi)有分區(qū),那么就需要對(duì)整個(gè)數(shù)據(jù)集執(zhí)行這些操作,這樣就會(huì)消耗大量資源。 所以常常根據(jù)日期和分類(lèi)對(duì)表進(jìn)行分區(qū),當(dāng)然利用某個(gè)標(biāo)識(shí)列ID也是很好的選擇。例如,電子商務(wù)數(shù)據(jù)庫(kù)的某張表可能包含了近6年的數(shù)據(jù),但是只定期訪問(wèn)本年度或某個(gè)月的數(shù)據(jù),那么就可以按年份或月份分區(qū),而另外一張表包含了近幾十種類(lèi)型商品的訂單,那么此時(shí)可以為每種類(lèi)型商品分一個(gè)區(qū)。 一般而言,衡量大型表是以數(shù)據(jù)為標(biāo)準(zhǔn)的,但對(duì)于適合分區(qū)的大型表,衡量大型表更重要的是對(duì)數(shù)據(jù)訪問(wèn)的性能,如果對(duì)于某些表的訪問(wèn)和維護(hù)有較嚴(yán)重的性能問(wèn)題,就可以視為大型表,就應(yīng)該考慮通過(guò)更好的設(shè)計(jì)和分區(qū)來(lái)解決性能問(wèn)題。 創(chuàng)建分區(qū)表必須經(jīng)過(guò)如下三個(gè)步驟: 1,? 創(chuàng)建分區(qū)函數(shù) 2,? 創(chuàng)建映射到分區(qū)函數(shù)的分區(qū)方案 3,? 創(chuàng)建使用該分區(qū)方案的分區(qū)表?
分區(qū)函數(shù)?
分區(qū)函數(shù)是數(shù)據(jù)庫(kù)中的一個(gè)獨(dú)立對(duì)象,它將表的行映射到一組分區(qū),所以分區(qū)函數(shù)解決的是HOW的問(wèn)題,即表如何分區(qū)的問(wèn)題。創(chuàng)建分區(qū)函數(shù)時(shí),必須指明數(shù)據(jù)分區(qū)的邊界點(diǎn)以及分區(qū)依據(jù)列,這樣便知道如何對(duì)表或索引進(jìn)行分區(qū)。分區(qū)函數(shù)的創(chuàng)建語(yǔ)法如下: CREATE PARTITION FUNCTION partition_function_name ( input_parameter_type ) AS RANGE [ LEFT | RIGHT ] FOR VALUES ( [ boundary_value [ ,...n ] ] ) [ ; ] 分區(qū)函數(shù)語(yǔ)法的相關(guān)解釋: 1,? 創(chuàng)建一個(gè)分區(qū)函數(shù)和創(chuàng)建一個(gè)普通的數(shù)據(jù)庫(kù)對(duì)象(例如表)沒(méi)什么區(qū)別。所以根據(jù)標(biāo)準(zhǔn)語(yǔ)法走就OK了。 2,? partition_function_name是分區(qū)函數(shù)的名稱(chēng)。分區(qū)函數(shù)名稱(chēng)在數(shù)據(jù)庫(kù)內(nèi)必須唯一,并且符合標(biāo)識(shí)符的規(guī)則。 3,? input_parameter_type是用于分區(qū)的列的數(shù)據(jù)類(lèi)型,習(xí)慣把它稱(chēng)為分區(qū)依據(jù)列。當(dāng)用作分區(qū)列時(shí),除 text、ntext、image、xml、timestamp、varchar(max)、nvarchar(max)、varbinary(max)、別名數(shù)據(jù)類(lèi)型或 CLR 用戶定義數(shù)據(jù)類(lèi)型外,其他所有數(shù)據(jù)類(lèi)型均有效。分區(qū)依據(jù)列是在 CREATE TABLE 或 CREATE INDEX 語(yǔ)句中指定的。 4,? boundary_value [ ,...n ]中的boundary_value是邊界值(或邊界點(diǎn)的值),n代表可以最多有n個(gè)邊界值,即n指定 boundary_value 提供的值的數(shù)目,但n不能超過(guò) 999。所創(chuàng)建的分區(qū)數(shù)等于 n + 1。不必按順序列出各值。如果值未按順序列出,則 Database Engine 將對(duì)這些邊界值進(jìn)行排序,創(chuàng)建分區(qū)函數(shù)并返回一個(gè)警告,說(shuō)明未按順序提供值。如果 n 包括任何重復(fù)的值,則數(shù)據(jù)庫(kù)引擎將返回錯(cuò)誤。邊界值的取值一定是和分區(qū)依據(jù)列相關(guān)的,所以只能使用 CREATE TABLE 或 CREATE INDEX 語(yǔ)句中指定的一個(gè)分區(qū)列。 5,? LEFT | RIGHT 指定boundary_value [ ,...n ] 的每個(gè)boundary_value屬于每個(gè)邊界值間隔的哪一側(cè)(左側(cè)還是右側(cè))。如果未指定,則默認(rèn)值為 LEFT。 例如我們可以依據(jù)某個(gè)表的int列來(lái)創(chuàng)建分區(qū)函數(shù): create partition function MyPF1(int) range left??? --默認(rèn)是left,所以可以省略left for values(500000,1000000,1500000) 很明顯,這個(gè)分區(qū)函數(shù)創(chuàng)建了4個(gè)分區(qū),因?yàn)榇藭r(shí)n=3,所以分區(qū)總數(shù)是n+1=4。而那個(gè)int分區(qū)依據(jù)列表明將要分區(qū)的那個(gè)表里面一定有一列是int類(lèi)型,是分區(qū)依據(jù)列。這個(gè)分區(qū)函數(shù)我們用的是range left,各個(gè)分區(qū)的取值范圍如下表:| 分區(qū) | 取值范圍 |
| 1 | (負(fù)無(wú)窮,500000] |
| 2 | [500001,1000000] |
| 3 | [1000001,1500000] |
| 4 | [1500001,正無(wú)窮) |
?
如果換成range right,即創(chuàng)建分區(qū)函數(shù)時(shí)代碼如下: create partition function MyPF1(int) range right for values(500000,1000000,1500000) 那么各個(gè)分區(qū)的取值范圍如下表:| 分區(qū) | 取值范圍 |
| 1 | (負(fù)無(wú)窮,499999] |
| 2 | [500000,999999] |
| 3 | [1000000,1499999] |
| 4 | [1500000,正無(wú)窮) |
?
我們還可以根據(jù)日期列創(chuàng)建分區(qū)函數(shù),例如: create partition function MyPF2(datetime) range right for values('2008/01/01', '2009/01/01') 這個(gè)分區(qū)函數(shù)非常適合查詢和歸檔某一年的數(shù)據(jù)。各個(gè)分區(qū)的取值范圍如下表:| 分區(qū) | 取值范圍 |
| 1 | <=2007/12/31 |
| 2 | [2008/01/01,2008/12/31] |
| 3 | >=2009/01/01 |
總結(jié)
以上是生活随笔為你收集整理的分区表理论解析(上):SQL Server 2k52k8系列(一)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 今天开始在博客园正式安家!
- 下一篇: 数据库时间字段排序问题