web-dev-qa-db-ja.com

月ごとにテーブルをパーティション化する方法( "YEAR&MONTH")と月ごとのパーティションを自動的に作成する方法は?

YearMonthの両方でテーブルをパーティション分割しようとしています。パーティション化する列は、ISO形式( '20150110'、20150202 'など)の日時タイプの列です。

たとえば、2010年、2011年、2012年の売上データがあるとします。データを年ごとにパーティション化し、各年も月ごとにパーティション化したいと思います。 (2010/01、2010/02、... 2010/12、2011/01、... 2015/01 ...)

E.X:

Sales2010Jan、Sales2010Feb、Sales2011Jan、Sales2011Feb、Sales2012Decなど.

私の質問は、それは可能ですか?もしそうなら、私はSSISを使用してプロセスをどのように自動化しますか?

10
Amr Tharwat

SSISはETL(抽出、変換、ロード)です。これはあなたがやりたいことではありません。 DDLステートメントを動的に作成する必要があるだけです。

以下の四半期で機能しますが、必要に応じて1、2、またはXか月でも機能します。

テーブルをパーティション分割する場合は、最初にファイル、ファイルグループ、パーティション分割テーブルを作成し、パーティション分割を手動で設定する必要があります

IntアイデンティティPKとdatetime2パーティション列を持つテーブルでの2015 Q1(前、Q1、およびQ2後)のN + 1パーティションの作成。更新して月を追加したり、毎月または必要なものにしたりしてください...

  • 最初にN個のファイルグループを作成します。

    _Alter Database [Test] Add Filegroup [Part_Before2015]
    Go
    Alter Database Test Add Filegroup [Part_201501]
    Go
    Alter Database Test Add Filegroup [Part_201504]
    Go
    _
  • ファイルグループごとにファイルを追加します。

    _Alter Database [Test] Add FILE ( NAME = N'Part_Before2015', FILENAME = N'...\Part_Before2015.ndf' , SIZE = 5120KB , FILEGROWTH = 1024KB ) TO Filegroup [Part_Before2015]
    Alter Database [Test] Add FILE ( NAME = N'Part_201501', FILENAME = N'...\Part_201501.ndf' , SIZE = 5120KB , FILEGROWTH = 1024KB ) TO Filegroup [Part_201501]
    Alter Database [Test] Add FILE ( NAME = N'Part_201504', FILENAME = N'...\Part_201504.ndf' , SIZE = 5120KB , FILEGROWTH = 1024KB ) TO Filegroup [Part_201504]
    _
  • Datetime2タイプ(または日付、さらには日時)にパーティション関数を作成します。

    _Create Partition Function RangePartFunction (datetime2)
    as Range Right For Values ('20150101', '20150401') 
    _
  • 各ファイルグループ(N + 1)のパーティション関数を使用してパーティション構成を作成します。

    _Create Partition Scheme RangePartScheme as Partition RangePartFunction
    To ([Part_Before2015], [Part_201501], [Part_201504])
    _
  • パーティション構成にパーティションテーブルを作成します。

    _Create TABLE [PartitionTable] (id int identity(0, 1) not null, date datetime2 not null, text char(8000))
    On RangePartScheme (date) ;
    _
  • パーティション化された列とパーティション構成にクラスター化インデックスを追加します。

    _Create Clustered Index IDX_Part On dbo.PartitionTable(date) 
        On RangePartScheme (date);
    _
  • PKをid列に追加します。

    _Alter Table dbo.PartitionTable Add COntraint PK_Part Primary Key Nonclustered(id, date);
    _

正しい境界の後に追加のファイルグループを追加するために使用されるクエリを作成し、最後のパーティションを分割する

  • パーティション構成の拡張とパーティション機能の分割を確認する
  • 使用するDMVを確認する
  • このすべてを確認し、それを使用して動的SQLを作成する方法

    _Declare @currentDate datetime2
    Declare @endDate datetime2 = '20160701' -- new end date
    Declare @dateAdd int = 3 -- Add 3 month = 1 Quarter
    
    -- Get Current boundaries 
    Select @currentDate = DATEADD(MONTH, @dateAdd,Cast(MAX(value) as datetime2)) From sys.partition_range_values as r
        Inner Join sys.partition_functions as f on r.function_id = f.function_id
    Where f.name = 'RangePartFunction'
    
    -- Get all quarters between max and end date
    ; with d(id, date, name) as (
        Select 0, @currentDate, Convert(char(6), @currentDate, 112)
        Union All
        Select id+1, DATEADD(MONTH, @dateAdd, date), Convert(char(6), DATEADD(MONTH, @dateAdd, date), 112)
        From d Where d.date <= @endDate
    )
    Select * From (
        Select id = id*10, query = 'If Not Exists(Select 1 From sys.filegroups Where name = ''Part_'+name+''')
            Begin 
                Print ''Create Filegroup [Part_'+name+']''
                Alter Database [Test] Add Filegroup [Part_'+name+']
            End
            GO'
        From d
        Union All
        Select id*10+1, 'If Not Exists(Select 1 From sys.sysfiles Where name = ''Part_'+name+''')
            Begin 
                Print ''Create File [Part_'+name+'.ndf]''
                Alter Database [Test] Add FILE ( NAME = N''Part_'+name+''', FILENAME = N''C:\DB\MSSQL11.MSSQLSERVER\MSSQL\DATA\Part_'+name+'.ndf'' , SIZE = 5120KB , FILEGROWTH = 1024KB ) TO Filegroup [Part_'+name+']
            End
            GO'
        From d
        Union All
        Select id*10+2, 'Print ''Add Range [Part_'+name+']''
            Alter Partition Scheme RangePartScheme Next Used [Part_'+name+']
            Go'
        From d
        Union All
        Select id*10+3, 'Print ''Split Function ['+Convert(char(8), date, 112)+']''
            Alter Partition Function RangePartFunction() Split Range ('''+Convert(char(8), date, 112)+''');
            Go'
        From d
    ) as q order by id
    _

このクエリの出力は、順番に実行する必要があるSQLクエリのリストです。

動的SQLを実行する

  • 手動で実行できます(SSMSでコピーして貼り付ける)
  • Whileループで、または出力テーブルの各行を1つずつ実行するカーソルで実行できます(sp_executesqlを使用)。

オートメーション

  • SQLクエリを実行するSQL Serverジョブを作成します。動的SQLの作成に使用したクエリを実行し、その出力をテーブル変数に保存してから、ループ/カーソルを使用して各ステートメントを実行します

毎月実行して、次の12か月が常に作成されるようにする場合は、これを使用してくださいSet @endDate = DATEADD(MONTH, 12, getdate())

最後に

  • 関数の最後の境界と@endDateの間のN個の不足している四半期に対して4 * N行を出力します。

    • ファイルグループを作成
    • ファイルグループにファイルを作成
    • パーティションスキームの範囲を拡張する
    • パーティション関数の範囲を分割する
  • カーソルまたはwhileループを使用して行ごとに実行するか、SMSSにコピーして貼り付けることができます。

  • つまり、ジョブで自動化することもできます。 @endDate = DATEADD(MONTH, 3, getdate()は次の3か月を作成します
  • 月次パーティションが必要な場合は、@ dateAddを1に変更します
  • 独自の列またはチェックを追加する

リンク

ジョブの作成= https://www.mssqltips.com/sqlservertip/3052/simple-way-to-create-a-sql-server-job-using-tsql/

sp_executesql = https://technet.Microsoft.com/en-us/library/ms188001%28v=sql.110%29.aspx

Whileループ= https://dba.stackexchange.com/questions/57933/can-exec-work-with-while-loop-of-cursor

18