The NoteBook of EricKong

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

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

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

          V2※高捷

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

          一、 摘要

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

          u  SQL Server2005 分區(qū)

          u  技術(shù)討論

          u  會議決議

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

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

          (1)       scale up VS scale out

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

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

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

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

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

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

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

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

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

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

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

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

          (2)       不同的訪問模式

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

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

          (1)       垂直分區(qū)

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

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

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

          應(yīng)該慎用垂直分區(qū),因為分析多個分區(qū)中的數(shù)據(jù)時需要聯(lián)接表的查詢。如果分區(qū)過大,垂直分區(qū)還可能會影響性能。

          (2)       水平分區(qū)

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

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

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

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

          表列數(shù)

           columns 

          記錄行

           Rows 

          每行大小

           Bytes/Row 

          需要頁數(shù)

           Pages 

          表大小

           A

          47

          1,600,000

          4600

          1,600,000

          12G

          先對其進(jìn)行垂直分區(qū),假設(shè)此表為一個主鍵,我們將其分為三個表,分區(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

          合計:

          7G

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

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

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

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

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

          2 使用方法

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

          5、  水平分區(qū)

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

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

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

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

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

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

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

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

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

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

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

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

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

          3、  分區(qū)實現(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ù)庫引擎 按升序從左到右排序時, boundary_value [ ,...n ] 屬于每個邊界值間隔的哪一側(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ū)指定的文件組,那么剩余的文件組將會做為下一次分區(qū)指定時使用,所以多出來的文件組也不會存在數(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ū)鍵值的行位于哪個分區(qū)中?

          SELECT $PARTITION . myRangePF1( col1)

          4、  分區(qū) DEMO

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

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

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

          實現(xiàn)腳本:

          ALTER TABLE [Production]. [TransactionHistory]

          SWITCH PARTITION 1

          TO [Production]. [TransactionHistoryArchive] PARTITION 2;

          實現(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)表。

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

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

          posted on 2010-09-03 09:26 Eric_jiang 閱讀(449) 評論(0)  編輯  收藏 所屬分類: 數(shù)據(jù)庫
          主站蜘蛛池模板: 丹江口市| 任丘市| 惠水县| 上蔡县| 和平区| 墨玉县| 扎囊县| 美姑县| 通海县| 滁州市| 仪征市| 桂平市| 榕江县| 保山市| 咸丰县| 泗阳县| 涞水县| 马公市| 高尔夫| 绥阳县| 江阴市| 喀喇| 来凤县| 壶关县| 彝良县| 靖宇县| 景东| 兖州市| 缙云县| 房产| 蒙阴县| 西贡区| 长汀县| 黎川县| 志丹县| 南木林县| 时尚| 河北区| 乌苏市| 中超| 吉木乃县|