The NoteBook of EricKong

            BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
            611 Posts :: 1 Stories :: 190 Comments :: 0 Trackbacks

          常用鏈接

          留言簿(11)

          我參與的團(tuán)隊(duì)

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          以前的一次技術(shù)例會(huì)內(nèi)容,拿出來共享一下,大家有問題可以提出來,一起提高。

          技術(shù)會(huì)議- SQL Server Partitioning

          V2※高捷

          本月技術(shù)會(huì)議專題為數(shù)據(jù)庫分區(qū)( SQL Server Partitioning ),主要講述為什么要分區(qū),在什么情況下需要對(duì)數(shù)據(jù)進(jìn)行分區(qū),如何進(jìn)行分區(qū),分區(qū)表管理等內(nèi)容。

          一、 摘要

              分區(qū)基礎(chǔ)知識(shí)

          u  SQL Server2005 分區(qū)

          u  技術(shù)討論

          u  會(huì)議決議

          二、 分區(qū)技術(shù)知識(shí)

          1、  為什么要分區(qū)?

          (1)       scale up VS scale out

          首先需要理解 scale up  scale out 的含義, scale up (向上擴(kuò)展),即后端大型服務(wù)器以增加處理器等運(yùn)算資源進(jìn)行升級(jí)以獲得對(duì)應(yīng)用性能的要求,提高硬件來提高數(shù)據(jù)處理及提高性能的一種方式。而 scale out (向外擴(kuò)展)主要是指根據(jù)需求增加不同的服務(wù)器應(yīng)用,依靠多部服務(wù)器協(xié)同運(yùn)算,借負(fù)載平衡及容錯(cuò)等功能來提高運(yùn)算能力及可靠度的方式來提高數(shù)據(jù)處理和提高性能的一種方式。數(shù)據(jù)庫分區(qū)技術(shù)的應(yīng)用則是 scale out 的體現(xiàn)。在此需要注意的是 Scale Out 方案始終面臨著數(shù)據(jù)集中的問題,即拆分過的數(shù)據(jù)在服務(wù)器邏輯體系中仍然是各自相對(duì)集中的而非無限隨意拆分。如果大量的邏輯放在數(shù)據(jù)庫服務(wù)器一端,數(shù)據(jù)庫服務(wù)器將會(huì)使得系統(tǒng)失去 Scale out 的能力和可能。因此,要保證 Scale out 的能力就必須保證數(shù)據(jù)庫只處理實(shí)質(zhì)性的數(shù)據(jù)提交和不可避免的數(shù)據(jù)查詢,對(duì)于能夠避免的數(shù)據(jù)查詢和非實(shí)質(zhì)性數(shù)據(jù)提交都應(yīng)該想辦法予以避免。而具體的策略和方案相對(duì)沒有最優(yōu)的方法。

          (2)       避免昂貴的硬件開銷

          使用分區(qū)技術(shù)處理大容量數(shù)據(jù)表,可以讓我們不必為了性能而購(gòu)買昂貴的新服務(wù)器或者提高服務(wù)器硬件性能來提高性能。

          (3)       使數(shù)據(jù)在一個(gè)合適的 Level 上管理

          使用分區(qū)技術(shù)后,我們?cè)趯?duì)數(shù)據(jù)庫進(jìn)行管理時(shí),避免了面對(duì) G 級(jí)別的數(shù)據(jù)量維護(hù),只需要面對(duì)幾百兆或者幾十兆的數(shù)據(jù),這樣使得我們面對(duì)數(shù)據(jù)庫管理時(shí),處于一個(gè)合適的水平和級(jí)別,就能保證數(shù)據(jù)庫的高維護(hù)性,節(jié)約維護(hù)成本、資源

          (4)       消除性能瓶頸,最小化維護(hù)成本

          同樣使用分區(qū)技術(shù)后,客戶端對(duì)數(shù)據(jù)庫的操作也更容易更迅速,提高了數(shù)據(jù)庫的性能,對(duì)數(shù)據(jù)庫維護(hù)也相對(duì)簡(jiǎn)單,比如說數(shù)據(jù)的備份、恢復(fù)等等。

          2、  什么情況下使用數(shù)據(jù)庫分區(qū)

          (1)       大數(shù)據(jù)量表(管理 / 索引創(chuàng)建 / 索引重建 / 備份與恢復(fù) / 擴(kuò)充 

          面對(duì)大表,你首先遇到的一個(gè)管理的問題,因?yàn)閿?shù)據(jù)量太大,管理非常復(fù)雜和麻煩。其次是索引,在大數(shù)據(jù)量表進(jìn)行索引的建立、重建都會(huì)有可能因?yàn)槌瑫r(shí)而導(dǎo)致失敗。再次是表的維護(hù),例如備份、恢復(fù)等有可能因?yàn)殚L(zhǎng)時(shí)間的操作影響其他用戶的操作,最后還有一個(gè)表的擴(kuò)充的問題,比如說擴(kuò)充字段、鎖的升級(jí)。

          在此,需要特別講述一下有關(guān)索引的問題,在 OLTP  On-Line Transaction Processing )和 DSS  Decision Support Systems )系統(tǒng)中,索引在上述兩種系統(tǒng)中的應(yīng)用是不同,在 OLTP 系統(tǒng)中,可能我們需要很少的索引,而在 DSS 系統(tǒng)中,我們肯定需要大量的索引,同時(shí)我們?cè)?/span> OLTP 系統(tǒng)中對(duì)索引的重建和碎片整理需要經(jīng)常性的去處理,而對(duì)于 DSS 系統(tǒng),對(duì)于索引我們?cè)瓌t上只需要一次即可。

          在備份與恢復(fù)的層面上分析, OLTP 是一個(gè)需要經(jīng)常備份、存放很多關(guān)鍵數(shù)據(jù)的、需要保持高可用性的比較小型的 VLDB( VERY LARGE DATE BASE ) 的系統(tǒng),而 DSS 是一個(gè)不需要經(jīng)常備份、數(shù)據(jù)也非關(guān)鍵數(shù)據(jù)但需要保高可用的大型 VLDB 系統(tǒng)。

          (2)       不同的訪問模式

          一種訪問模式主要指聯(lián)機(jī)事務(wù)處理的方式,比如一些插入、更新、刪除等內(nèi)容。另一種訪問模式主要是對(duì)數(shù)據(jù)庫的查詢、分析等操作,這些主要是一些 SELECT 的操作。

          3、  分區(qū)策略( Partitioning Strategies 

          (1)       垂直分區(qū)

          垂直分區(qū)將一個(gè)表分為多個(gè)表,每個(gè)表包含較少的列。垂直分區(qū)包括兩種類型,即規(guī)范化和行拆分:

          規(guī)范化是標(biāo)準(zhǔn)的數(shù)據(jù)庫進(jìn)程,它刪除表中的多余列,并將這些列放置在通過主鍵和外鍵關(guān)系鏈接到主表的輔助表中。

          行拆分將原始表垂直分成多個(gè)只包含較少列的表。拆分表內(nèi)的每個(gè)邏輯行都與其他表內(nèi)由 UNIQUE KEY 列(在所有已分區(qū)表中都相同)標(biāo)識(shí)的相同邏輯行相匹配。例如,聯(lián)接每個(gè)拆分表內(nèi)具有 ID 712 的行將重新創(chuàng)建原始行。

          應(yīng)該慎用垂直分區(qū),因?yàn)榉治龆鄠€(gè)分區(qū)中的數(shù)據(jù)時(shí)需要聯(lián)接表的查詢。如果分區(qū)過大,垂直分區(qū)還可能會(huì)影響性能。

          (2)       水平分區(qū)

          水平分區(qū)將表分為多個(gè)表。這樣,每個(gè)表包含的列數(shù)相同,但是行更少。例如,可以將一個(gè)包含十億行的表水平分區(qū)成 12 個(gè)表,每個(gè)小表表示特定年份內(nèi)一個(gè)月的數(shù)據(jù)。任何需要特定月的數(shù)據(jù)的查詢都只引用相應(yīng)的表。

          具體如何將表進(jìn)行水平分區(qū)取決于如何分析數(shù)據(jù)。您應(yīng)將表進(jìn)行分區(qū),以便查詢引用的表盡可能少。否則,查詢時(shí)需要使用過多的 UNION 查詢來邏輯合并表,這會(huì)影響查詢性能。

          4、  垂直分區(qū)案例

          某個(gè)表存在記錄行為 1,600,000 rows 。此表有 47 個(gè)列, 4600Bytes/Row ,由于 SQL Server 本身系統(tǒng)限制一條記錄不能超過 8060Bytes ,所以我們一行記錄需要一頁,每條記錄浪費(fèi) 3460Bytes ,這樣計(jì)算后整個(gè)表空間占用約 12G 。表內(nèi)容如下所示:

          表列數(shù)

           columns 

          記錄行

           Rows 

          每行大小

           Bytes/Row 

          需要頁數(shù)

           Pages 

          表大小

           A

          47

          1,600,000

          4600

          1,600,000

          12G

          先對(duì)其進(jìn)行垂直分區(qū),假設(shè)此表為一個(gè)主鍵,我們將其分為三個(gè)表,分區(qū)標(biāo)準(zhǔn)如下表所示:

          表列數(shù)

           columns 

          記錄行

           Rows 

          每行大小

           Bytes/Row 

          需要頁數(shù)

           Pages 

          表大小

           1

          14

          1,600,000

          1000

          200,000

          1.6G

           2

          18

          1,600,000

          1600

          320,000

          2.5G

           3

          17

          1,600,000

          2000

          400,000

          3.2G

          合計(jì):

          7G

          結(jié)果:節(jié)省了 5G 的空間,同時(shí)提高了性能。

          另外在進(jìn)行垂直分區(qū)的時(shí)候還需要注意一下幾點(diǎn):

          1 優(yōu)化行的尺寸

             因?yàn)?/span> SQL Server 在對(duì)數(shù)據(jù)進(jìn)行檢索的時(shí)候,是通過頁來取得的,這就要求我們盡量讓更多的記錄在一個(gè)頁上,才能保證更多的行在緩存中,這樣就保證了數(shù)據(jù)庫在進(jìn)行 I/O 操作時(shí),提高了性能。

              另外,從鎖的方面分析,我們將列分區(qū)后,在進(jìn)行操作時(shí),列鎖定的是沒有分區(qū)表的幾個(gè)字段,而不是所有的字段,這就保證了另外兩個(gè)表不被鎖限制,也就降低了行鎖對(duì)數(shù)據(jù)庫并發(fā)用戶的影響。

          2 使用方法

             首先考慮將經(jīng)常關(guān)聯(lián)的邏輯列進(jìn)行分組,也就說將同一類屬性,經(jīng)常放在一起進(jìn)行查詢劃分為一個(gè)分組放到一個(gè)表中,從而減少表與表之間的交流和關(guān)聯(lián);其次要考慮到那些列是只讀的,那些是 OLTP 環(huán)境下的列,這樣可以避免數(shù)據(jù)檢索時(shí)的重復(fù)性,提高性能。

          5、  水平分區(qū)

          水平分區(qū)創(chuàng)造出了更多的可管理的塊,同時(shí)減少的 DBA 對(duì)表的維護(hù)的影響,例如表索引管理、備份恢復(fù)等。另外,他減少的鎖對(duì)數(shù)據(jù)操作的影響,使得我們?cè)趯?duì)部分?jǐn)?shù)據(jù)進(jìn)行操作時(shí),鎖僅僅在某一個(gè)部分進(jìn)行,減少了鎖操作對(duì)數(shù)據(jù)庫資源的占用,從而提高了數(shù)據(jù)處理的效率。

          三、 SQL Server2005 分區(qū)實(shí)現(xiàn)

          1、  SQL Server2005 分區(qū)表和索引概念

          物理分區(qū),具有標(biāo)準(zhǔn)表和索引相關(guān)的所有的屬性和功能

          大型表或索引經(jīng)過分區(qū)后更容易管理,因?yàn)榉謪^(qū)后可以更快速有效地管理和訪問數(shù)據(jù)子集,同時(shí)維護(hù)數(shù)據(jù)集合的完整性。通過分區(qū),從 OLTP  OLAP 系統(tǒng)加載數(shù)據(jù)操作只需要幾秒鐘,同時(shí)由于對(duì)數(shù)據(jù)子集執(zhí)行的維護(hù)操作只是針對(duì)所需數(shù)據(jù)而不是整個(gè)表,因此效率也得到了很大的提高。

          已分區(qū)表和已分區(qū)索引的數(shù)據(jù)劃分為分布于一個(gè)數(shù)據(jù)庫中多個(gè)文件組的單元,數(shù)據(jù)俺水平方式分區(qū),因此多組行映射到單個(gè)的分區(qū)中。單個(gè)索引或表的所有分區(qū)都必須位于同一個(gè)數(shù)據(jù)庫中。

           SQL Server2005 中,數(shù)據(jù)庫中所有表和索引都視為已分區(qū)表和索引,即使這些表和索引只包含一個(gè)分區(qū)。

          2、  分區(qū)設(shè)計(jì)

          (1)       創(chuàng)建分區(qū)函數(shù);

          分區(qū)函數(shù):分區(qū)函數(shù)定義如何根據(jù)某些列的值將表或索引的行映射到一組分區(qū)。(一張表最多有 1000 個(gè)分區(qū))

          (2)       創(chuàng)建分區(qū)方案;

          分區(qū)方案:分區(qū)方案將分區(qū)函數(shù)指定的每個(gè)分區(qū)映射到文件組。(一個(gè)分區(qū)方案只能使用一個(gè)分區(qū)函數(shù),但是,一個(gè)分區(qū)函數(shù)可以參與到多個(gè)分區(qū)方案)

          (3)       在創(chuàng)建表和索引的時(shí)候,指定表或索引的分區(qū)方案。

          3、  分區(qū)實(shí)現(xiàn)

          (1)       創(chuàng)建分區(qū)函數(shù)

          CREATE PARTITION FUNCTION partition_function_name ( input_parameter_type )

          AS RANGE [ LEFT | RIGHT ]

          FOR VALUES ( [ boundary_value [ ,...n ] ] ) [ ; ]

          例句:

          CREATE PARTITION FUNCTION myRangePF1( DATETIME ) AS RANGE RIGHT FOR VALUES ( '2007-12-21' , '2007-12-22' , '2007-12-23' , '2007-12-24' , '2007-12-25' , '2007-12-26' )

          說明:指定當(dāng)間隔值由 數(shù)據(jù)庫引擎 按升序從左到右排序時(shí), boundary_value [ ,...n ] 屬于每個(gè)邊界值間隔的哪一側(cè)(左側(cè)還是右側(cè))。如果未指定,則默認(rèn)值為 LEFT 

          (2)       創(chuàng)建分區(qū)方案

          CREATE PARTITION SCHEME partition_scheme_name

          AS PARTITION partition_function_name

          [ ALL ] TO ( { file_group_name | [ PRIMARY ] } [ ,...n ] )[ ; ]

                      例句:

                      CREATE PARTITION SCHEME mySchemePS1 AS PARTITION [myRangePF1] TO ( [PRIMARY], [FG1], [FG2], [FG3], [FG4], [FG5], [FG6], [FG7])

          說明:如果創(chuàng)建的文件組少于要分區(qū)的指定的文件組,創(chuàng)建語句將執(zhí)行失敗,如果創(chuàng)建的文件組大于要分區(qū)指定的文件組,那么剩余的文件組將會(huì)做為下一次分區(qū)指定時(shí)使用,所以多出來的文件組也不會(huì)存在數(shù)據(jù)。

          (3)       增加分區(qū)

          ALTER PARTITION SCHEME partition_scheme_name

          NEXT USED [ filegroup_name ] [ ; ]

          例句:

          ALTER PARTITION SCHEME MyRangePS1

          NEXT USED test5fg;

          說明:修改分區(qū)方案后,需要修改分區(qū)函數(shù)。

          ALTER PARTITION FUNCTION partition_function_name()

          {  SPLIT RANGE ( boundary_value )

            | MERGE RANGE ( boundary_value ) } [ ; ]

          例句:

          ALTER PARTITION FUNCTION myRangePF1 ()

          SPLIP RANGE ( 100);

          (4)       合并分區(qū)

          ALTER PARTITION FUNCTION myRangePF1 ()

          MERGE RANGE (100);

          (5)       創(chuàng)建分區(qū)表

          CREATE TABLE PatitionTable( col1 int , col2 char ( 10))

          ON MyRangePS1( col1);

          (6)       創(chuàng)建分區(qū)索引

          CREATE INDEX ix_Col2 ON PartitionTable( col2)

          ON myRangePS1( col1);

          CREATE INDEX ix_Col2 ON PartitionTable( col2)

          說明:如果是根據(jù)分區(qū)依據(jù)列來創(chuàng)建索引,則不需要增加 On 后的內(nèi)容。

          (7)       分區(qū)信息查看

           使用 $PARTITION 函數(shù)

           訪問已分區(qū)表的分區(qū)子集中的所有行。

          SELECT $PARTITION . myRangePF1( col1), count (*)

          FROM PartitionTable

          GROUP BY $Partition . myRangePF1( col1)

          ※確定包含特定分區(qū)鍵值的行位于哪個(gè)分區(qū)中?

          SELECT $PARTITION . myRangePF1( col1)

          4、  分區(qū) DEMO

          示例數(shù)據(jù)為 SQL Server2005 自帶的 AdventureWorks 數(shù)據(jù)庫,在這個(gè)數(shù)據(jù)庫中有兩個(gè)表 TransactionHistory (交易歷史信息表)和 TransactionHistoryArchive (交易歷史歸檔表), TransactionHistory 主要維護(hù)年度最新事務(wù)信息,而 TransactionHistoryArchive 保存歷史的事務(wù)信息。

          TransactionHistory 設(shè)定為 12 個(gè)分區(qū),存放了 03  9 月份到 04 年八月份的數(shù)據(jù), TransactionHistoryArchive 分為 2 個(gè)區(qū),存放了 03  9 月份之前和之后的數(shù)據(jù),分區(qū)字段為 TransactionDate 

          每個(gè)月開始, TransactionHistory 當(dāng)前最早的一個(gè)月的數(shù)據(jù)將被切換到 TransactionHistoryArchive 表中。需要注意的是,在這個(gè)操作中,如果不使用分區(qū),而是使用導(dǎo)入導(dǎo)出或 INSERT 等語句進(jìn)行數(shù)據(jù)的切換,是非常耗費(fèi)資源和時(shí)間的,而采用分區(qū),則避免了這個(gè)問題,因?yàn)樵谡嬲牟僮髦校?/span> SQL Server 并不是真正的將數(shù)據(jù)進(jìn)行了遷移,而只是將源數(shù)據(jù)進(jìn)行了切換,就是說數(shù)據(jù)的指針或者說數(shù)據(jù)資源表位置進(jìn)行了修改,所以表分區(qū)之間的數(shù)據(jù)切換是瞬間的事情。

          實(shí)現(xiàn)腳本:

          ALTER TABLE [Production]. [TransactionHistory]

          SWITCH PARTITION 1

          TO [Production]. [TransactionHistoryArchive] PARTITION 2;

          實(shí)現(xiàn):見 SQL 腳本。

          5、  條碼物流系統(tǒng)分區(qū)應(yīng)用介紹

          目前部門所規(guī)劃的 5 大產(chǎn)品之一條碼物流系統(tǒng)在開發(fā)中使用到了數(shù)據(jù)庫分區(qū)技術(shù)來改善數(shù)據(jù)庫性能,目前應(yīng)用只是輪胎狀態(tài)表。

          因?yàn)檩喬顟B(tài)表貫穿于整個(gè)條碼物流系統(tǒng)的各個(gè)工序和環(huán)節(jié),也存放著大量的生產(chǎn)、質(zhì)檢等數(shù)據(jù),數(shù)據(jù)量非常巨大,在沒有進(jìn)行分區(qū)時(shí)整個(gè)表的檢索經(jīng)常出現(xiàn)檢索超時(shí)和客戶端死機(jī)的情況。

          輪胎狀態(tài)表的分區(qū)主要依據(jù)于輪胎胎號(hào),將 08 年之前的信息,按年分區(qū),而 08 年之后的數(shù)據(jù)按照每 10 周進(jìn)行分區(qū),目前應(yīng)用良好,對(duì)整個(gè)現(xiàn)場(chǎng)系統(tǒng)的應(yīng)用和 WEB 系統(tǒng)的查詢性能都有了很大的改善。

          posted on 2010-09-03 09:26 Eric_jiang 閱讀(451) 評(píng)論(0)  編輯  收藏 所屬分類: 數(shù)據(jù)庫
          主站蜘蛛池模板: 津市市| 乌海市| 宁德市| 中卫市| 合川市| 邛崃市| 新泰市| 伽师县| 福建省| 河源市| 香港 | 芦溪县| 郑州市| 玉门市| 英超| 沛县| 辛集市| 成安县| 台湾省| 奇台县| 紫阳县| 云安县| 昌宁县| 奉节县| 全椒县| 日喀则市| 色达县| 东源县| 贵港市| 沧州市| 子长县| 乌拉特中旗| 五家渠市| 呈贡县| 九江县| 什邡市| 乌鲁木齐县| 衡阳县| 红原县| 乃东县| 元阳县|