<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    The NoteBook of EricKong

      BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
      611 Posts :: 1 Stories :: 190 Comments :: 0 Trackbacks
       你是否在千方百計優化SQL Server 數據庫的性能?如果你的數據庫中含有大量的表格,把這些表格分區放入獨立的文件組可能會讓你受益匪淺。SQL Server 2005引入的表分區技術,讓用戶能夠把數據分散存放到不同的物理磁盤中,提高這些磁盤的并行處理性能以優化查詢性能。

      SQL Server數據庫表分區操作過程由三個步驟組成:

      1. 創建分區函數

      2. 創建分區架構

      3. 對表進行分區

      下面將對每個步驟進行詳細介紹。

      步驟一:創建一個分區函數

      此分區函數用于定義你希望SQL Server如何對數據進行分區的參數值(how)。這個操作并不涉及任何表格,只是單純的定義了一項技術來分割數據。

      我們可以通過指定每個分區的邊界條件來定義分區。例如,假定我們有一份Customers表,其中包含了關于所有客戶的信息,以一一對應的客戶編號(從1到1,000,000)來區分。我們將通過以下的分區函數把這個表分為四個大小相同的分區:  

    CREATE PARTITION FUNCTION customer_partfunc (int
    AS RANGE RIGHT 
    FOR VALUES (250000, 500000, 750000)

      這些邊界值定義了四個分區。第一個分區包括所有值小于250,000的數據,第二個分區包括值在250,000到49,999之間的數據。第三個分區包括值在500,000到7499,999之間的數據。所有值大于或等于750,000的數據被歸入第四個分區。

      請注意,這里調用的"RANGE RIGHT"語句表明每個分區邊界值是右界。類似的,如果使用"RANGE LEFT"語句,則上述第一個分區應該包括所有值小于或等于250,000的數據,第二個分區的數據值在250,001到500,000之間,以此類推。

      步驟二:創建一個分區架構

      一旦給出描述如何分割數據的分區函數,接著就要創建一個分區架構,用來定義分區位置(where)。創建過程非常直截了當,只要將分區連接到指定的文件組就行了。例如,如果有四個文件組,組名從"fg1"到"fg4",那么以下的分區架構就能達到想要的效果:  

    CREATE PARTITION SCHEME customer_partscheme 
    AS PARTITION customer_partfunc 
    TO (fg1, fg2, fg3, fg4)

      注意,這里將一個分區函數連接到了該分區架構,但并沒有將分區架構連接到任何數據表。這就是可復用性起作用的地方了。無論有多少數據庫表,我們都可以使用該分區架構(或僅僅是分區函數)。

      步驟三:對一個表進行分區

      定義好一個分區架構后,就可以著手創建一個分區表了。這是整個分區操作過程中最簡單的一個步驟。只需要在表創建指令中添加一個"ON"語句,用來指定分區架構以及應用該架構的表列。因為分區架構已經識別了分區函數,所以不需要再指定分區函數了。

      例如,使用以上的分區架構創建一個客戶表,可以調用以下的Transact-SQL指令:  

    CREATE TABLE customers (FirstName nvarchar(40), LastName nvarchar(40), CustomerNumber int) 
    ON customer_partscheme (CustomerNumber)

      關于SQL Server的表分區功能,你知道上述的相關知識就足夠了。記住!編寫能夠用于多個表的一般的分區函數和分區架構就能夠大大提高可復用性。

             數據庫性能調優是每一個優秀SQL Server管理員最終的責任。雖然保證數據的安全和可用性是我們的最高的目標,但是假如數據庫應用程序無法滿足用戶的要求,那么DBA們會因為性能低下的設計和實現而受到指責。SQL Server 2005在數據庫性能方面得到了很多提高,尤其是表分區的技術。如果你還沒不了解表分區的特征,那么請你花點時間讀這篇文章。

      表分區的概念不是一個新的概念;只要你當過一段時間的SQL Server DBA,那么你可能已經對一些頻繁訪問的表進行過歸檔,當這個表中的歷史數據變的不再經常被訪問的時候。比如,假設你有一個打印時間報表的應用,你的報告很少會查詢1995年的數據,因為絕大部分的預算規劃會基于最近幾年的數據。

      在SQL Server的早期版本中,你可以創建多個表。每一個表都具有相同的列結構,用來保存不同年份的數據。這樣,當存在著對歷史數據訪問的必要的時候,你可以創建一個視圖來對這些表進行查詢處理。將數據保存在多個表中是很方便的,因為相對于查詢時掃描整個大表,掃描小表會更快。但是這種好處只有在你預先知道哪些時間段的數據會被訪問。同時,一旦數據過期,你還需要創建新表并且轉移新產生的歷史數據。

      SQL Server 7和SQL Server 2000支持分布式分區視圖(distributed partitioned views,又稱為物化視圖,materialized views).分布式分區視圖由分布于多臺服務器上的、具有相同表結構的表構成,而且你還需要為每一個服務器增加鏈接服務器定義(linked server definitions),最后在其中一臺服務器上創建一個視圖將每臺服務器上返回的數據合并起來。這里的設計思想是數據庫引擎可以利用多臺服務器的處理能力來滿足查詢。

      但是,分布式分區視圖(DPV)受到很多限制,你可以在SQL Server的在線幫助文檔中閱讀到。雖然DPV在一些情況下能夠提供性能上的提高,但是這種技術不能被廣泛的應用。已經被證明它們不能滿足逐步增長的企業級應用的要求。何況,DPV的實現是一個費力的過程,需要DBA進行很多工作。

      SQL Server 2005開始支持表分區,這種技術允許所有的表分區都保存在同一臺服務器上。每一個表分區都和在某個文件組(filegroup)中的單個文件關聯。同樣的一個文件/文件組可以容納多個分區表。

      在這種設計架構下,數據庫引擎能夠判定查詢過程中應該訪問哪個分區,而不用掃描整個表。如果查詢需要的數據行分散在多個分區中,SQL Server使用多個處理器對多個分區進行并行查詢。你可以為在創建表的時候就定義分區的索引。 對小索引的搜索或者掃描要比掃描整個表或者一張大表上的索引要快很多。因此,當對大表進行查詢,表分區可以產生相當大的性能提升。

      現在讓我們通過一個簡單的例子來了解表分區是如何發揮作用的。在這篇文章中,我不想深入到分區的語法細節當中,這些你可以在SQL Server的在線幫助文檔中找到。下面的例子基于存儲著一個時間報表系統的數據的數據倉庫。除了默認的文件組,我另外創建了7個文件組,每一個文件組僅包含一個文件,這個文件將存儲由分區函數定義的一部分數據。

      為了測試表分區的性能提升,我向這個分區表中插入了一千五百萬行,同時向另外一個具有相同表結構、但是沒有進行分區的表插入了同樣的數據。對分區表執行的INSERT語句運行的更快一些。甚至在我的內存不到1G的筆記本電腦上,對分區表的INSERT語句比不分區的表的INSERT語句要快上三倍。當然,查詢的執行時間依據硬件資源的差異而所有變化,但是你還是能夠在你的環境中感到不同程度的提升。

      我將檢查更深入了一步,通過分別檢查同一條返回所有行的、簡單SELECT語句在分區表和非分區表上的執行計劃,返回的數據范圍通過WHERE語句來指定。同一條語句在這兩個不同的表上有不同的執行計劃。對于分區表的查詢顯示出一個嵌套的循環和索引的掃描。從本質上來說,SQL Server將兩個分區視為獨立的表,因此使用一個嵌套循環將它們連接起來。對非分區的表的同一個查詢則使用索引掃描來返回同樣的列。當你使用同樣的分區策略創建多個表,同時在查詢中連接這些表,那么性能上的提升會更加明顯

    你可以使用下面的查詢來了解每一個分區中的行的個數:

      SELECT $PARTITION.TimeEntryDateRangePFN(time_entry_date) AS Partition, 
    COUNT(*) AS [COUNT] FROM fact_time_entry 
    GROUP BY $PARTITION.TimeEntryDateRangePFN(time_entry_date) 
    ORDER BY Partition

      表分區對交易環境和數據倉庫環境來說,都是一個重要的特征。數據倉庫用戶最主要的抱怨是移動事實表(fact table)會花費太多時間。當裝載數據到事實表的時候,用戶查詢(立方體處理查詢)的性能會明顯下降,甚至是完全無法成功。因此,裝載大量的數據到事實表的時候常常需要停機。如果使用表分區,就不再出現這樣的情況——確切的講,你一眨眼的工夫就可以移動事實表。為了演示這是如何生效的,我使用上面例子中相同的分區函數和表結構來創建一個新的表,這個表叫做fact_time_entry2。表的主鍵從五千萬開始,這樣fact_time_entry2就不會包含表fact_time_entry中已經有的數據。

      現在我把2007年的數據移動到這張fact_time_entry2中。同時讓我們假設fact_time_entry表中包含著2007年之前的數據。在fact_time_entry2表完成數據的轉移,我執行下面的語句:

      ALTER TABLE fact_time_entry2 
    SWITCH PARTITION 8 TO fact_time_entry PARTITION 8

      這條語句將編號為8的分區,這個分區恰好包含著2007年的數據,從fact_time_entry2移動到了fact_time_entry表中,在我的筆記本電腦上,這個過程只花費了3毫秒。在這短短的3毫秒中,我的事實表就增加了五百萬條記錄!的確,我需要在交換分區之前,將數據移動到中間表,但是我的用戶不需要擔心——事實表隨時都可以查詢!在這幕后,實際上沒有數據移動——只是兩張表的元數據發生了變化。

      我可以使用類似的查詢刪除事實表中不在需要的數據。例如,假設我們決定我們不再關心2004年的記錄。下面的語句可以將這些記錄轉移到我們創建的工作表中:

      ALTER TABLE fact_time_entry 
    SWITCH PARTITION 2 TO fact_time_entry2 PARTITION 2

      這樣的語句依舊在毫秒級內完成了。現在,我可以刪除fact_time_entry2或者將它移到其他的服務器上。我的事實表不會包含2004年的任何記錄。這個分區還是需要在目的表中存在,而且它必須是空的。你不能將分區轉移到一個包含重復數據的表中。源表和目的表的分區必須一致,同時被轉移的數據必須在同一個文件組中。即使受到這么多的限制,轉換分區和無需停機就可以移動數據表的功能必將讓數據倉庫的實現變的前所未有的輕松。

    SQL Server 表分區(partitioned table/Data Partitioning)
    Partitioned Table
            可伸縮性性是數據庫管理系統的一個很重要的方面,在SQL Server 2005中可伸縮性方面提供了表分區功能。
            其實對于有關系弄數據庫產品來說,對表、數據庫和服務器進行數據分區的從而提供大數據量的支持并不是什么新鮮事,但 SQL Server 2005 提供了一個新的體系結構功能,用于對數據庫中的文件組進行表分區。水平分區可根據分區架構,將一個表劃分為幾個較小的分組。表分區功能是針對超大型數據庫(從數百吉字節到數千吉字節或更大)而設計的。超大型數據庫 (VLDB) 查詢性能通過分區得到了改善。通過對廣大分區列值進行分區,可以對數據的子集進行管理,并將其快速、高效地重新分配給其他表。
            設想一個大致的電子交易網站,有一個表存儲了此網站的歷史交易數據,這此數據量可能有上億條,在以前的SQL Server版本中存儲在一個表中不管對于查詢性能還是維護都是件麻煩事,下面我們來看一下在SQL Server2005怎么提高性能和可管理性:
    -- 創建要使用的測試數據庫,Demo
    USE [master]
    IF EXISTS (SELECT name FROM master.dbo.sysdatabases WHERE name = N'DEMO')
    DROP DATABASE [DEMO]
    CREATE DATABASE [DEMO]
    --由于表分區使用使用新的體系結構,使用文件組來進行表分區,所以我們創建將要用到的6個文件組,來存儲6個時間段的交易數據[<2000],[ 2001], [2002], [2003], [2004], [>2005]
    ALTER DATABASE Demo ADD FILEGROUP YEARFG1;
    ALTER DATABASE Demo ADD FILEGROUP YEARFG2;
    ALTER DATABASE Demo ADD FILEGROUP YEARFG3;
    ALTER DATABASE Demo ADD FILEGROUP YEARFG4;
    ALTER DATABASE Demo ADD FILEGROUP YEARFG5; 
    ALTER DATABASE Demo ADD FILEGROUP YEARFG6; 
    -- 下面為這些文件組添加文件來進行物理的數據存儲
    ALTER DATABASE Demo ADD FILE (NAME = 'YEARF1', FILENAME = 'C:"ADVWORKSF1.NDF') TO FILEGROUP YEARFG1;
    ALTER DATABASE Demo ADD FILE (NAME = 'YEARF2', FILENAME = 'C:"ADVWORKSF2.NDF') TO FILEGROUP YEARFG2;
    ALTER DATABASE Demo ADD FILE (NAME = 'YEARF3', FILENAME = 'C:"ADVWORKSF3.NDF') TO FILEGROUP YEARFG3;
    ALTER DATABASE Demo ADD FILE (NAME = 'YEARF4', FILENAME = 'C:"ADVWORKSF4.NDF') TO FILEGROUP YEARFG4;
    ALTER DATABASE Demo ADD FILE (NAME = 'YEARF5', FILENAME = 'C:"ADVWORKSF5.NDF') TO FILEGROUP YEARFG5;
    ALTER DATABASE Demo ADD FILE (NAME = 'YEARF6', FILENAME = 'C:"ADVWORKSF6.NDF') TO FILEGROUP YEARFG6;
    -- HERE WE ASSOCIATE THE PARTITION FUNCTION TO 
    -- THE CREATED FILEGROUP VIA A PARTITIONING SCHEME
    USE DEMO;
    GO
    -------------------------------------------------------
    -- 創建分區函數
    -------------------------------------------------------
    CREATE PARTITION FUNCTION YEARPF(datetime)
    AS 
    RANGE LEFT FOR VALUES ('01/01/2000'
    ,'01/01/2001'
    ,'01/01/2002'
    ,'01/01/2003'
    ,'01/01/2004')
    -------------------------------------------------------
    -- 創建分區架構
    -------------------------------------------------------
    CREATE PARTITION SCHEME YEARPS
    AS PARTITION YEARPF TO (YEARFG1, YEARFG2,YEARFG3,YEARFG4,YEARFG5,YEARFG6)
    -- 創建使用此Schema的表
    CREATE TABLE PARTITIONEDORDERS
    (
    ID INT NOT NULL IDENTITY(1,1),
    DUEDATE DATETIME NOT NULL,
    ) ON YEARPS(DUEDATE)
    --為此表填充數據
    declare @DT datetime
    SELECT @DT = '1999-01-01'
    --start looping, stop at ending date
    WHILE (@DT <= '2005-12-21')
    BEGIN
        INSERT INTO PARTITIONEDORDERS VALUES(@DT) 
       SET @DT=dateadd(yy,1,@DT)
    END
          -- 現在我們可以看一下我們剛才插入的行都分布在哪個Partition 
    SELECT *, $PARTITION.YEARPF(DUEDATE) FROM PARTITIONEDORDERS
          --我們可以看一下我們現在PARTITIONEDORDERS表的數據存儲在哪此partition中,以及在這些分區中數據量的分布
    SELECT * FROM SYS.PARTITIONS WHERE OBJECT_ID = OBJECT_ID('PARTITIONEDORDERS')
    --
            --現在我們設想一下,如果我們隨著時間的流逝,現在已經到了2005年,按照我們先前的設定,我們想再想入一個分區,這時是不是重新創建表分區架構然后重新把數據導放到新的分區架構呢,答案是完全不用。下面我們就看如果新加一個分區。
           --更改分區架構定義語言,讓下一個分區使用和現在已經存在的分區YEARFG6分區中,這樣此分區就存儲了兩段partition的數據。
    ALTER PARTITION SCHEME YEARPS
    NEXT USED YEARFG6;
           --更改分區函數
    ALTER PARTITION FUNCTION YEARPF()
    SPLIT RANGE ('01/01/2005') 
           --現在我們可以看一下我們剛才插入的行都分布在哪個Partition?
    SELECT *, $PARTITION.YEARPF(DUEDATE) FROM PARTITIONEDORDERS
          --我們可以看一下我們現在PARTITIONEDORDERS表的數據存儲在哪此partition中,以及在這些分區中

    posted on 2010-09-03 09:38 Eric_jiang 閱讀(902) 評論(0)  編輯  收藏 所屬分類: 數據庫
    主站蜘蛛池模板: 最近中文字幕大全中文字幕免费 | 精品亚洲一区二区| 欧洲亚洲国产清在高| 久久亚洲精品无码gv| a级片免费在线播放| 18勿入网站免费永久| 亚洲国模精品一区| 亚洲综合熟女久久久30p| 久久丫精品国产亚洲av| 国产尤物在线视精品在亚洲| 免费av片在线观看网站| 免费AA片少妇人AA片直播| 久久久久噜噜噜亚洲熟女综合| 亚洲国产夜色在线观看| 中文字幕在线免费看| 妞干网免费视频在线观看| 久久亚洲国产成人亚| 亚洲一线产品二线产品| 中文字幕无码日韩专区免费| 精品久久免费视频| 久久被窝电影亚洲爽爽爽| 日韩精品无码免费一区二区三区| 免费又黄又爽的视频| 亚洲第一区二区快射影院| 无码人妻久久一区二区三区免费 | 无码色偷偷亚洲国内自拍| 久久久久久精品免费看SSS | 国产情侣久久久久aⅴ免费| 亚洲国产精品久久久久久| 一日本道a高清免费播放| 日本一道综合久久aⅴ免费| 亚洲av极品无码专区在线观看| 久久一区二区三区免费播放| 亚洲导航深夜福利| 中文字幕视频免费| 亚洲AV成人片无码网站| 久久亚洲一区二区| 国产精品美女自在线观看免费| 亚洲天堂2017无码中文| 免费人成在线观看视频高潮| 亚洲一级片在线播放|