2017-10-22 15 views
1

ストアドプロシージャを実行し、その結果をデスティネーションデータベースのテーブルFinancialStatementIdsとして格納するSSISパッケージを作成しています。テーブルは既に宛先データベースに存在します。私は、宛先テーブルを分割し、それを行うためのスクリプトを書いている必要があります。日時フィールドの年基準に基づくパーティショニングテーブル

私は過去5年間の情報を取得しており、その年に基づいて各パーティションを保存しています。だから私はプライマリパーティションを除外する5つのパーティションを作成し、パーティションはdatetimeフィールドであるperiodanddateというカラムに設定されています。それが正しいことを確認してください。私はまた、スクリプトは、それがFinancialStatementIdsテーブルに

Destinatonテーブル

enter image description here

を分割する必要があることを知っているか知りたいのですが、私はパーティションテーブル

内の他の列を追加する必要がありますか テーブルfinancialstatementIdsため

USE CoreReferenceStaging; 
GO 
-- Adds four new filegroups to the CoreReferenceStaging database 
ALTER DATABASE CoreReferenceStaging 
ADD FILEGROUP CT1; 
GO 
ALTER DATABASE CoreReferenceStaging 
ADD FILEGROUP CT2; 
GO 
ALTER DATABASE CoreReferenceStaging 
ADD FILEGROUP CT3; 
GO 
ALTER DATABASE CoreReferenceStaging 
ADD FILEGROUP CT4; 
GO 
ALTER DATABASE CoreReferenceStaging 
ADD FILEGROUP CT5; 


-- Adds one file for each filegroup. 
ALTER DATABASE CoreReferenceStaging 
ADD FILE 
( 
    NAME = ctdata1, 
    FILENAME = 'E:\MSSQL10_50.SQL2008R2\MSSQL\DATA\ctdata1.ndf', 
    SIZE = 5MB, 
    MAXSIZE = 100MB, 
    FILEGROWTH = 5MB 
) 
TO FILEGROUP CT1; 
ALTER DATABASE CoreReferenceStaging 
ADD FILE 
( 
    NAME = ctdata2, 
    FILENAME = 'E:\MSSQL10_50.SQL2008R2\MSSQL\DATA\ctdata2.ndf', 
    SIZE = 5MB, 
    MAXSIZE = 100MB, 
    FILEGROWTH = 5MB 
) 
TO FILEGROUP CT2; 
GO 
ALTER DATABASE CoreReferenceStaging 
ADD FILE 
( 
    NAME = ctdata3, 
    FILENAME = 'E:\MSSQL10_50.SQL2008R2\MSSQL\DATA\ctdata3.ndf', 
    SIZE = 5MB, 
    MAXSIZE = 100MB, 
    FILEGROWTH = 5MB 
) 
TO FILEGROUP CT3; 
GO 
ALTER DATABASE CoreReferenceStaging 
ADD FILE 
( 
    NAME = ctdata4, 
    FILENAME = 'E:\MSSQL10_50.SQL2008R2\MSSQL\DATA\ctdata4.ndf', 
    SIZE = 5MB, 
    MAXSIZE = 100MB, 
    FILEGROWTH = 5MB 
) 
TO FILEGROUP CT4; 
GO 
ALTER DATABASE CoreReferenceStaging 
ADD FILE 
( 
    NAME = ctdata5, 
    FILENAME = 'E:\MSSQL10_50.SQL2008R2\MSSQL\DATA\ctdata5.ndf', 
    SIZE = 5MB, 
    MAXSIZE = 100MB, 
    FILEGROWTH = 5MB 
) 
TO FILEGROUP CT5; 
GO 

-- Creates a partition function called financialStatementPartition that will partition a table into four partitions 
CREATE PARTITION FUNCTION financialStatementPartition (datetime) 
    AS RANGE LEFT FOR VALUES (year(getDate()), year(getDate() -1), year(getDate() -2),year(getDate() -4)) ; 
GO 
-- Creates a partition scheme called financialStatementRange that applies financialStatementPartition to the five filegroups created above 
CREATE PARTITION SCHEME financialStatementRange 
    AS PARTITION financialStatementPartition 
    TO (CT1, CT2, CT3, CT4,CT5) ; 
GO 
-- Creates a partitioned table called FinancialStatementPartition that uses financialStatementRange to partition periodenddate 
CREATE TABLE FinancialStatementPartition (periodenddate datetime PRIMARY KEY) 
    ON financialStatementRange (periodenddate) ; 
GO 

DDL

CREATE TABLE [dbo].[FinancialStatementIds](
    [financialCollectionId] [int] NOT NULL, 
    [companyId] [int] NOT NULL, 
    [dataItemId] [int] NOT NULL, 
    [dataItemName] [varchar](200) NULL, 
    [dataItemvalue] [decimal](18, 0) NULL, 
    [unittypevalue] [int] NULL, 
    [fiscalyear] [int] NULL, 
    [fiscalquarter] [int] NULL, 
    [periodenddate] [datetime] NULL, 
    [filingdate] [datetime] NULL, 
    [restatementtypename] [varchar](200) NULL, 
    [latestforfinancialperiodflag] [bit] NULL, 
    [latestfilingforinstanceflag] [bit] NULL, 
    [currencyconversionflag] [int] NULL, 
    [currencyname] [varchar](200) NULL, 
    [periodtypename] [varchar](200) NULL 
) ON [PRIMARY] 

答えて

1

時間コンポーネントを持つ一時的な型でパーティショニングする場合は、RANGE RIGHTを使用します。これにより、パーティションの境界と正確に一致する日付が目的のパーティションとファイルグループに配置されます。

パーティション関数境界の日付計算式が正しくありません。現在の日付から整数を減算する代わりに、DATEADDを使用する必要があります。これは、日数を減算するものとして解釈されます。

次のスクリプトは、将来の2018年の境界を含む、2013年から2018年までの(2013年に実行されたと仮定して)2013年から2018年のパーティション機能とスキームを作成します。スライディング・ウィンドウ・パーティション化のベスト・プラクティスは、空のパーティションを分割して、スプリット中の高価なデータ移動を回避し(ロギングはDMLの約4倍)、空のパーティションが分割されるとデータが移動しないようにしますパーティションにデータをロードする前に実行してください。このスクリプトでは、すべてのファイルグループと基本ファイルが既に存在することを前提としています。

CREATE PARTITION FUNCTION financialStatementPartition (datetime) 
    AS RANGE RIGHT FOR VALUES(); 
--the first permanent partition (always empty) 
CREATE PARTITION SCHEME financialStatementRange 
    AS PARTITION financialStatementPartition 
    ALL TO ([PRIMARY]); 
DECLARE @periodenddate datetime = DATEADD(year, -4, DATEADD(year, DATEDIFF(year, '', GETDATE()), '')); 
ALTER PARTITION SCHEME financialStatementRange 
      NEXT USED CT1; 
ALTER PARTITION FUNCTION financialStatementPartition() 
      SPLIT RANGE(@periodenddate); 
SET @periodenddate = DATEADD(year, 1, @periodenddate); 
ALTER PARTITION SCHEME financialStatementRange 
      NEXT USED CT2; 
ALTER PARTITION FUNCTION financialStatementPartition() 
      SPLIT RANGE(@periodenddate); 
SET @periodenddate = DATEADD(year, 1, @periodenddate); 
ALTER PARTITION SCHEME financialStatementRange 
      NEXT USED CT3; 
ALTER PARTITION FUNCTION financialStatementPartition() 
      SPLIT RANGE(@periodenddate); 
SET @periodenddate = DATEADD(year, 1, @periodenddate); 
ALTER PARTITION SCHEME financialStatementRange 
      NEXT USED CT4; 
ALTER PARTITION FUNCTION financialStatementPartition() 
      SPLIT RANGE(@periodenddate); 
SET @periodenddate = DATEADD(year, 1, @periodenddate); 
ALTER PARTITION SCHEME financialStatementRange 
      NEXT USED CT5; 
ALTER PARTITION FUNCTION financialStatementPartition() 
      SPLIT RANGE(@periodenddate); 
--create partition for future 2018 year 
SET @periodenddate = DATEADD(year, 1, @periodenddate); 
ALTER PARTITION SCHEME financialStatementRange 
      NEXT USED CT6; 
ALTER PARTITION FUNCTION financialStatementPartition() 
      SPLIT RANGE(@periodenddate); 

私はFinancialStatementPartitionテーブルの目的やパーティション化の理由を理解していません。 dbo.FinancialStatementIdsテーブルをパーティション分割するには、パーティション化されたクラスタ化インデックスを作成します。その表のスクリーン・ショットには、このタスクを実行するための重要な詳細である既存の索引は含まれていません。分かりやすくするために、実際のCREATE TABLE DDLにインデックスと制約を追加してください。

クラスタ化インデックスキーには、キーの一部としてパーティション化列を含める必要があることに注意してください。また、主キーと一意の制約を含むすべての一意の索引は、索引を整列させるために、キーの一部として区分化列を含める必要があります。

以下の例では、クラスタ化インデックスを作成してヒープを分割しています。

CREATE CLUSTERED INDEX cdx ON dbo.FinancialStatementIds(datetime) 
      ON financialStatementRange(periodenddate); 

ヒープを分割し、既存のデータを保持し、代わりにパーティションクラスタ化インデックスを作成するのではなく、同じスキーマが異なる名前で新しいパーティションテーブルのテーブルを作成し、INSERTを使用してロード... SELECT、古いテーブルを削除するには新しいテーブルの名前を元の名前に変更します。以下はスクリプトです。

CREATE TABLE [dbo].[FinancialStatementIds_Partitioned](
    [financialCollectionId] [int] NOT NULL, 
    [companyId] [int] NOT NULL, 
    [dataItemId] [int] NOT NULL, 
    [dataItemName] [varchar](200) NULL, 
    [dataItemvalue] [decimal](18, 0) NULL, 
    [unittypevalue] [int] NULL, 
    [fiscalyear] [int] NULL, 
    [fiscalquarter] [int] NULL, 
    [periodenddate] [datetime] NULL, 
    [filingdate] [datetime] NULL, 
    [restatementtypename] [varchar](200) NULL, 
    [latestforfinancialperiodflag] [bit] NULL, 
    [latestfilingforinstanceflag] [bit] NULL, 
    [currencyconversionflag] [int] NULL, 
    [currencyname] [varchar](200) NULL, 
    [periodtypename] [varchar](200) NULL 
) ON financialStatementRange(periodenddate); 
GO 

INSERT INTO dbo.FinancialStatementIds_Partitioned 
SELECT * 
FROM dbo.FinancialStatementIds WITH(TABLOCKX); 
GO 
DROP TABLE dbo.FinancialStatementIds; 
GO 
EXEC sp_rename N'dbo.FinancialStatementIds_Partitioned', N'FinancialStatementIds'; 
GO 

は、2013年から2018年2014から2019に、この6年間のウィンドウをスライドさせ最古毎年パーティションからデータを削除し、次の将来の年のための新しいものを作成します。 SQL Server 2016以降では、 TRUNCATE TABLE...WITH(PARTITIONS...))を使用して特定のパーティションからデータを削除できます。例:

TRUNCATE TABLE dbo.FinancialStatementIds 
WITH (PARTITIONS($PARTITION.financialStatementPartition('20130101'))); 

SQL Server 2014以前では、このタスクのステージングテーブルに切り替える必要があります。これは、同一のスキーマを持つ整列したステージング表を作成することによって行われます。

CREATE TABLE [dbo].[FinancialStatementIds_Staging](
     [financialCollectionId] [int] NOT NULL, 
     [companyId] [int] NOT NULL, 
     [dataItemId] [int] NOT NULL, 
     [dataItemName] [varchar](200) NULL, 
     [dataItemvalue] [decimal](18, 0) NULL, 
     [unittypevalue] [int] NULL, 
     [fiscalyear] [int] NULL, 
     [fiscalquarter] [int] NULL, 
     [periodenddate] [datetime] NULL, 
     [filingdate] [datetime] NULL, 
     [restatementtypename] [varchar](200) NULL, 
     [latestforfinancialperiodflag] [bit] NULL, 
     [latestfilingforinstanceflag] [bit] NULL, 
     [currencyconversionflag] [int] NULL, 
     [currencyname] [varchar](200) NULL, 
     [periodtypename] [varchar](200) NULL 
) ON financialStatementRange(periodenddate); 
GO 
CREATE INDEX idx ON dbo.FinancialStatementIds_Partitioned_Staging(financialCollectionId); 
GO 

最も古い年のデータをステージングテーブルに移動し、ステージングテーブルを切り捨てて年のデータを永久に削除します。最も古い年のパーティションが空になったら、関数から境界を削除します。これは最初の2つの空のパーティションを1つの空のパーティションにマージします。

ALTER TABLE FinancialStatementIds 
SWITCH PARTITION $PARTITION.financialStatementPartition('20130101') 
TO FinancialStatementIds_Staging PARTITION $PARTITION.financialStatementPartition('20130101'); 

TRUNCATE TABLE FinancialStatementIds_Staging; 

ALTER PARTITION FUNCTION financialStatementPartition() 
    MERGE RANGE ('20130101'); 
GO 

は次に、新しいファイルグループを作成した後、次の将来の年のためのパーティションを作成します。

ALTER PARTITION SCHEME financialStatementRange 
    NEXT USED CT7; 
ALTER PARTITION FUNCTION financialStatementPartition() 
    SPLIT RANGE('20190101'); 

注異なるファイルグループにパーティションを配置する必要がありません。ファイルが別のストレージに置かれている特殊な使用例では、別のファイルグループにパーティションを配置するとパフォーマンスが向上する可能性がありますが、ここでは該当しません。複数のファイルグループを使用する特定の理由がない限り、すべてのパーティションを同じファイルグループに配置することで複雑さを回避できます。

+0

私は少しあなたの答えと混同しています。あなたの答えにファイルグループ、ファイル、パーティションスキームの宣言はありません。私がパーティション分割に慣れていて、仮定に頼ることができないので、最終的な解決策が何を含んでいるのか教えてください。また、このテーブルにはインデックスがないことをご了承ください。年の基準に基づいてテーブルを分割する必要があります。それは本当にFinancialStatementIdsテーブルのインデックスを持つ必要がありますか? – Tom

+0

@Tomでは、ファイルグループとファイルに変更は必要ありませんでした。空のパーティション関数とスキームスクリプトを追加し、ヒープを分割して既存のデータを保持する方法を追加しました。仮定を避けるために、テーブルDDLを質問に追加してください。すべてのテーブルにクラスタ化インデックスがあることをお勧めします。 –

+0

Dan、financialstatementIdsテーブル – Tom

関連する問題