web-dev-qa-db-ja.com

テーブル内のパーティション間でのデータの移動

パーティションを持つテーブルが1つあり、パーティション関数とスキームは次のように定義されています。

 CREATE PARTITION FUNCTION DateRangePF (CHAR(8))
  AS RANGE RIGHT FOR VALUES ('20180101','20190101')

 CREATE PARTITION SCHEME DateRangePS 
  AS PARTITION DateRangePF TO (Y2018FG, Y2019FG);

境界値 '20190101'のパーティションに多くのデータがあり、次の境界値と関連するファイルグループで4つの部分に分割することにしました。

  • '20190101'、ファイルグループはY012019FG、
  • '20190401'、ファイルグループはY042019FG、
  • '20190701'、ファイルグループはY072019FG、
  • '20191001'、ファイルグループはY102019FG。

さて、境界値「20190101」の古い単一パーティションからこれらの4つのパーティションにデータを切り替えるための最良の戦略は何でしょうか?

2

さて、境界値「20190101」の古い単一パーティションからこれらの4つのパーティションにデータを切り替えるための最良の戦略は何でしょうか?

パーティションテーブルが整列していると想定して、パーティションのメンテナンスには、同様にパーティション分割されたステージングテーブルを使用します。これにより、空でないパーティションが分割されたときに、コストのかかるデータの移動とログ記録が回避されます。

以下は、質問のDDLから収集した例です。 2つの境界を持つパーティション関数は3つのパーティションを作成するため、パーティションスキームDDLは正しくないことに注意してください。最初は2018年より前のデータ用です。3つのパーティションはすべてファイルグループにマップする必要があるため、ここではPRIMARYを使用しました脚本。 DATEは8と比較して行ごとに4バイトしか必要ないため、パーティション列のデータ型にDATEではなくCHAR(8)を選択した理由がわかりません。

--1) create a staging partition function, scheme, and aligned staging table like the original but with different names:

CREATE PARTITION FUNCTION DateRangePF_Staging (CHAR(8))
    AS RANGE RIGHT FOR VALUES ('20180101','20190101');

CREATE PARTITION SCHEME DateRangePS_Staging
    AS PARTITION DateRangePF_Staging TO ([PRIMARY], [Y2018FG], [Y2019FG]);

 CREATE TABLE YourTable_Staging (
      PartitioningColumn CHAR(8) NOT NULL
    , OtherColumn int NOT NULL
) ON DateRangePS_Staging(PartitioningColumn);

CREATE CLUSTERED INDEX cidx 
    ON YourTable_Staging(PartitioningColumn) 
    ON DateRangePS_Staging(PartitioningColumn);
CREATE NONCLUSTERED INDEX ncidx 
    ON YourTable_Staging(OtherColumn)
    ON DateRangePS_Staging(PartitioningColumn);
GO


--2) `SWITCH` the '20190101' partition into the staging table:

 ALTER TABLE YourTable
    SWITCH PARTITION $PARTITION.DateRangePF('20190101')
    TO YourTable_Staging PARTITION $PARTITION.DateRangePF_Staging('20190101');

--3) split the original partition function to create new boundaries (the split partition is empty after `SWITCH`):

ALTER PARTITION SCHEME DateRangePS
    NEXT USED Y2019FG;
ALTER PARTITION FUNCTION DateRangePF()
    SPLIT RANGE('20190401');
ALTER PARTITION SCHEME DateRangePS
    NEXT USED Y2019FG;
ALTER PARTITION FUNCTION DateRangePF()
    SPLIT RANGE('20190701');
ALTER PARTITION SCHEME DateRangePS
    NEXT USED Y2019FG;
ALTER PARTITION FUNCTION DateRangePF()
    SPLIT RANGE('20191001');
GO

--4) repartition the staging table and indexes using the original partition scheme:    

CREATE CLUSTERED INDEX cidx 
    ON YourTable_Staging(PartitioningColumn) 
    WITH(DROP_EXISTING=ON)    
    ON DateRangePS(PartitioningColumn);
CREATE NONCLUSTERED INDEX ncidx 
    ON YourTable_Staging(OtherColumn)
    WITH(DROP_EXISTING=ON)    
    ON DateRangePS(PartitioningColumn);

ALTER TABLE YourTable_Staging
    SWITCH PARTITION $PARTITION.DateRangePF('20190101')
    TO YourTable PARTITION $PARTITION.DateRangePF('20190101');
ALTER TABLE YourTable_Staging
    SWITCH PARTITION $PARTITION.DateRangePF('20190401')
    TO YourTable PARTITION $PARTITION.DateRangePF('20190401');
ALTER TABLE YourTable_Staging
    SWITCH PARTITION $PARTITION.DateRangePF('20190701')
    TO YourTable PARTITION $PARTITION.DateRangePF('20190701');
ALTER TABLE YourTable_Staging
    SWITCH PARTITION $PARTITION.DateRangePF('20191001')
    TO YourTable PARTITION $PARTITION.DateRangePF('20191001');
GO            

--5) update stats after SWITCH
UPDATE STATISTICS YourTable;    
GO

--6) drop staging objects
DROP TABLE YourTable_Staging;
DROP PARTITION SCHEME DateRangePS_Staging;
DROP PARTITION FUNCTION DateRangePF_Staging;
GO
2
Dan Guzman