68

私は2つの大きなテーブルSQL Server 2008 Entを持っています。サービスを中断せずOLTP databaseにこれらのテーブルを別のテーブルに移動するにはどうすればよいですか?filegroup現在、これらのテーブルでは、毎秒約100〜130のレコードが挿入され、30〜50のレコードが更新されています。各テーブルには、約1億のレコードと6つfieldのs(1つのフィールドを含むgeography)があります。

Googleで解決策を探していますが、すべての解決策に含まれています

2番目のテーブルの作成、最初のテーブルからの行の挿入、最初のテーブルの削除など

この問題を解決するためにパーティション関数を使用できますか?

4

10 に答える 10

88

テーブルを新しいファイルグループに移動するだけの場合は、必要な新しいファイルグループのテーブルにクラスター化インデックスを再作成する必要があります(結局のところ、クラスター化インデックステーブルデータです)。

あなたは例えばでこれを行うことができます:

CREATE CLUSTERED INDEX CIX_YourTable
   ON dbo.YourTable(YourClusteringKeyFields)
   WITH DROP_EXISTING
   ON [filegroup_name]

または、クラスター化されたインデックスが一意である場合:

CREATE UNIQUE CLUSTERED INDEX CIX_YourTable
   ON dbo.YourTable(YourClusteringKeyFields)
   WITH DROP_EXISTING
   ON [filegroup_name]

これにより、新しいクラスター化インデックスが作成され、既存のインデックスが削除され、指定したファイルグループに新しいクラスター化インデックスが作成されます。つまり、テーブルデータは新しいファイルグループに移動されました。

指定する可能性のあるすべての使用可能なオプションの詳細については、 CREATEINDEXに関するMSDNドキュメントを参照してください。

もちろん、これはまだパーティショニングを扱っていませんが、それ自体はまったく別の話です...

于 2010-03-13T10:50:43.613 に答える
32

この質問に答えるには、まず理解する必要があります

  • テーブルにインデックスがない場合、そのデータはヒープと呼ばれます
  • テーブルにクラスター化インデックスがある場合、そのインデックスは事実上テーブルデータです。したがって、クラスター化インデックスを移動すると、データも移動します。

最初のステップは、移動するテーブルに関する詳細情報を見つけることです。これを行うには、次のT-SQLを実行します。

sp_help N'<<your table name>>'

出力には、「Data_located_on_filegroup」というタイトルの列が表示されます。これは、テーブルデータがどのファイルグループにあるかを知るための便利な方法です。ただし、より重要なのは、テーブルのインデックスに関する情報を表示する出力です。(テーブルインデックスに関する情報のみを表示したい場合は、実行するだけですsp_helpindex N'<<your table name>>')テーブルには1)インデックスがない(ヒープである)、2)単一のインデックス、または3)複数のインデックスがある場合があります。index_descriptionが「clustered、unique、...」で始まる場合、それは移動するインデックスです。インデックスが主キーでもある場合、つまりOKの場合でも、インデックスを移動できます。

インデックスを移動するには、上記のヘルプクエリの結果に表示されているindex_nameとindex_keysをメモし、それらを使用し<<blanks>>て次のクエリに入力します。

CREATE UNIQUE CLUSTERED INDEX [<<name of clustered index>>]
ON [<<table name>>]([<<column name the index is on - from index_keys above>>])
WITH (DROP_EXISTING = ON, ONLINE = ON)
ON <<name of file group you want to move the index to>>

上記のDROP EXISTING, ONLINEオプションは重要です。 DROP EXISTINGインデックスが重複していないことを確認し、ONLINE移動中もテーブルをオンラインに保ちます(現在はEnterpriseバージョンでのみ使用可能です)。

移動するインデックスがクラスター化されたインデックスでないUNIQUE CLUSTERED場合は、上記を次のように置き換えます。NONCLUSTERED

ヒープテーブルを移動するには、クラスター化インデックスを追加し、上記のステートメントを実行して別のファイルグループに移動し、インデックスを削除します。

ここで、戻っsp_helpてテーブルを実行し、結果をチェックして、テーブルとインデックスデータが現在どこにあるかを確認します。

テーブルに複数のインデックスがある場合、上記のステートメントを実行してクラスター化インデックスを移動すると、クラスターsp_helpindex化インデックスが新しいファイルグループにあることが示されますが、残りのインデックスは元のファイルグループに残ります。テーブルは引き続き正常に機能しますが、インデックスを別のファイルグループに配置する必要があるのには十分な理由があります。テーブルとそのすべてのインデックスを同じファイルグループに含めるCREATE [NONCLUSTERED, or other] ... DROP EXISTING... 場合は、移動するインデックスのタイプに応じて、必要に応じて置き換えて、インデックスごとに上記の手順を繰り返します。

于 2015-07-10T23:28:17.523 に答える
7

パーティショニングは1つの解決策ですが、サービスを中断することなく、クラスター化されたインデックスを新しいファイルグループに「移動」できます(条件によっては、以下のリンクを参照)。

CREATE CLUSTERED /*oops*/ INDEX ... WITH (DROP_EXISTING = ON, ONLINE = ON, ...) ON newfilegroup

クラスタ化されたインデックスデータであり、これはファイルグループの移動と同じです。

CREATEINDEXをご覧ください

これは、主キーがクラスター化されているかどうかによって異なります。これにより、実行方法が変わります。

于 2010-03-13T10:52:02.617 に答える
2

SQL Server Books Onlineからのこの抜粋は、次のように述べています。「クラスター化インデックスのリーフレベルとデータページは定義上同じであるため、クラスター化インデックスを作成し、ONpartition_scheme_nameまたはONfilegroup_name句を使用すると、テーブルがファイルグループから効果的に移動します。新しいパーティションスキームまたはファイルグループに対してテーブルが作成された場所。」(ソース-http://msdn.microsoft.com/en-us/library/ms188783.aspx)from(http://www.mssqltips.com/sqlservertip/2442/move-data-between-sql-server-database -filegroups /

marc_sによる受け入れられた回答のように他の友人がすでに言っているように、スクリーンショットはSSMSGUIを使用してそれを行う別の方法を提供します。

[ストレージ]タブのインデックスプロパティから別のファイルグループに簡単に移動できることに注意してください ここに画像の説明を入力してください

于 2014-07-06T18:10:20.067 に答える
2

int, bit, datetimeクラスタ化インデックスを再作成すると、などの「プリミティブ」列のみが移動することに注意してください。

varchar(max), varbinary他の「blob」列を移動するには、テーブルを再作成する必要があります。ありがたいことに、SSMSでこれを半自動で行う方法があります。テーブルの[デザイン]ウィンドウで[テキストファイルグループ]を変更し、変更を保存します。

(2021年からのクイックアップデート):または、テーブル内のすべての値の新しいファイルグループを指す一時的な「パーティション化」ルール(パーティション化ルールはデータの移動先を決定する関数)を作成できます。このパーティショニングスキームを適用すると、実際にデータが移動します

詳細が必要な場合は、https://www.jitbit.com/alexblog/153-moving-sql-table-textimage-to-a-new-filegroup/でブログを書きました。

于 2018-10-13T22:31:07.097 に答える
1

テーブルを別のファイルグループに移動するにはどうすればよいですか?

注:テーブルを別のファイルグループに移動することは、EnterpriseEditionでのみ機能します。

ステップ1 :

どのファイルグループテーブルが存在するかを確認します。

-- Query to check the tables and their current filegroup:

SELECT    tbl.name AS [Table Name], 
          CASE WHEN dsidx.type='FG' THEN dsidx.name ELSE '(Partitioned)' END AS [File Group] 
FROM      sys.tables AS tbl 
JOIN      sys.indexes AS idx 
ON        idx.object_id = tbl.object_id 
AND       idx.index_id <= 1 
LEFT JOIN sys.data_spaces AS dsidx 
ON        dsidx.data_space_id = idx.data_space_id 
ORDER BY  [File Group], [Table Name] 

ステップ2 :

既存の1つまたは複数のテーブルを新しいファイルグループに移動します

テーブルを移動するファイルグループがまだ存在しない場合は、セカンダリファイルグループを作成してからテーブルを移動してください。

テーブルを別のファイルグループに移動するには、テーブルのクラスター化されたインデックスを新しいファイルグループに移動する必要があります。クラスタ化インデックスのリーフレベルには、実際にはテーブルデータが含まれています。したがって、クラスター化されたインデックスの移動は、次のようにDROP_EXISTING句を使用して1つのステートメントで実行できます。

CREATE UNIQUE CLUSTERED INDEX [Index_Name] ON [SchemaName].[TableName]
(
    [ClusteredIndexKeyFields]
)WITH (DROP_EXISTING = ON, ONLINE = ON) ON [FilegroupName]
GO

ステップ3:

残りの非クラスター化インデックスをセカンダリファイルグループに移動します

下記の構文を使用して、非クラスター化インデックスを手動で移動する必要があります。

--1st check the index information using the following sp
sp_helpindex [YourTableName]


--Now by using the following query you can move the remaining indexes to secondary filegroup
CREATE NONCLUSTERED INDEX [Index_Name] ON [SchemaName].[TableName]
(
    [IndexKeyFields]
)WITH (DROP_EXISTING = ON, ONLINE = ON) ON [FilegroupName]
GO

ヒープを別のファイルグループに移動する:

私が知っているように、ヒープを別のファイルグループに移動する唯一の方法は、新しいファイルグループにクラスター化されたインデックスを一時的に追加してから、それを削除することです(必要な場合)。

于 2017-03-23T12:58:31.073 に答える
1

SSMSで、[テーブル]を展開し、移動するテーブルを展開し、[インデックス]を展開して、クラスター化インデックスを右クリックし、[スクリプトインデックス]->[ドロップして作成]をクリックします。

これにより、スクリプトを含むクエリウィンドウが開き、クラスター化インデックスが削除され、元のインデックスと同じ仕様の新しいインデックスが作成されます。

クエリウィンドウ"ALTER TABLE <> ADD CONSTRAINT"のステートメントで、ステートメントの最後にある「ON」キーワードの後のファイルグループの名前を変更します。たとえば、テーブルがPRIMARYファイルグループにあり、「SECONDARY」という名前のファイルグループに移動する場合は、に変更"ON [PRIMARY]""ON [SECONDARY]"ます。
操作中にテーブルをオンラインのままにしておきたい場合は、に変更"ONLINE = OFF"してください"ONLINE = ON"

スクリプトを実行すると、元のスクリプトが削除され、指定されたファイルグループに新しいスクリプトが作成されます。

于 2021-03-17T19:36:55.193 に答える
0

これらの手順は、テーブルを別のファイルグループに(Management Studioを介して)移動するのに非常に簡単で簡単だと思います。

  • 各インデックスのFileGroupプロパティを変更するだけで、すべての非クラスター化インデックスを新しいファイルグループに移動します

  • クラスタインデックスを非クラスタに変更し、そのファイルグループを単純に変更します(前の手順のように)

  • このコマンド(またはIDE)を使用して、「新しいファイルグループ」を使用して新しい一時クラスターインデックスを追加します。

       CREATE CLUSTERED INDEX [PK_temp]
    ON YOURTABLE([Id])
      ON NEWFILEGROUP
    

    (上記のコマンドにより、すべてのデータが新しいファイルグループに移動されます)

  • 上記の一時的なPKを削除します(それが完全にその仕事をするとき!)

  • メインのクラスターインデックスをクラスターインデックスに戻します(IDEを介して)

上記の手順の利点は、既存のFK関係を削除する必要はありません。また、IDEを使用すると、エラー状態でデータが失われるのを防ぐことができます。

注:FileGroupに対してディスククォータが有効になっていないことを確認するか、正しく設定してください。そうしないと、「ファイルグループがいっぱいです」という例外が発生します。

于 2013-08-21T06:12:46.860 に答える
0
CREATE CLUSTERED INDEX IXC_Products_Product_id
ON dbo.Products(Product_id)
WITH (DROP_EXISTING = ON) ON MyNewFileGroup
于 2016-12-26T07:53:18.513 に答える
0

同じ問題があり、これは私が思いついたスクリプトです(テストされ、期待どおりに機能します):

DECLARE @Target_Filegroup sysname = N'XXX';
-----------------------------------------------------------------------------------------
;WITH [IX] AS(
SELECT
[Schema]                 = SCHEMA_NAME(so.[schema_id]) COLLATE DATABASE_DEFAULT,
[Object_Name]            = so.[name] COLLATE DATABASE_DEFAULT,
[Object_Type]            = so.[type],
[Is_Published]           = so.[is_published],
[Is_Schema_Published]    = so.[is_schema_published],
[IX_Name]                = ix.[name] COLLATE DATABASE_DEFAULT,
[IX_Type]                = ix.[type],
[IX_Type_Desc]           = ix.[type_desc] COLLATE DATABASE_DEFAULT,
[Is_PK]                  = ix.[is_primary_key],
[Is_Unique]              = ix.[is_unique],
[IX_Data_Space]          = ds.[name] COLLATE DATABASE_DEFAULT,
[Is_UC]                  = ix.[is_unique_constraint],
[FF]                     = ix.[fill_factor],
[Is_Padded]              = ix.[is_padded],
[Is_Disabled]            = ix.[is_disabled],
[Is_Hypothetical]        = ix.[is_hypothetical],
[Allow_Row_Locks]        = ix.[allow_row_locks],
[Allow_Page_Locks]       = ix.[allow_page_locks],
[Has_Filter]             = ix.[has_filter],
[Filter]                 = ix.[filter_definition] COLLATE DATABASE_DEFAULT,
--[auto_created]         = ix.[auto_created],
--[optimize_seq_key]     = ix.[optimize_for_sequential_key],
[Indexed_Columns] = STUFF(( SELECT [text()] = CONCAT(', ', QUOTENAME(COL_NAME(ic.[object_id],ic.[column_id])))
                            FROM sys.index_columns ic
                            WHERE ic.[object_id] = so.[object_id]
                            AND ic.[index_id] = ix.[index_id]
                            AND ic.[is_included_column] = 0
                            ORDER BY ic.[key_ordinal]
                            FOR XML PATH('')
                            ), 1, 2, '') COLLATE DATABASE_DEFAULT,
[Indexed_Columns_Order] = STUFF(( SELECT [text()] = CONCAT(', ', QUOTENAME(COL_NAME(ic.[object_id],ic.[column_id])), CASE [is_descending_key] WHEN 1 THEN ' DESC' ELSE ' ASC' END)
                            FROM sys.index_columns ic
                            WHERE ic.[object_id] = so.[object_id]
                            AND ic.[index_id] = ix.[index_id]
                            AND ic.[is_included_column] = 0
                            ORDER BY ic.[key_ordinal]
                            FOR XML PATH('')
                            ), 1, 2, '') COLLATE DATABASE_DEFAULT,
[Included_Columns] = STUFF(( SELECT [text()] = CONCAT(', ', QUOTENAME(COL_NAME(ic.[object_id],ic.[column_id])))
                            FROM sys.index_columns ic
                            WHERE ic.[object_id] = so.[object_id]
                            AND ic.[index_id] = ix.[index_id]
                            AND ic.[is_included_column] = 1
                            ORDER BY ic.[key_ordinal]
                            FOR XML PATH('')
                            ), 1, 2, '') COLLATE DATABASE_DEFAULT
FROM sys.objects so
LEFT JOIN sys.indexes ix ON so.[object_id] = ix.[object_id]
LEFT JOIN sys.data_spaces ds ON ix.[data_space_id] = ds.[data_space_id]
WHERE so.[type] IN ('U', 'V')
AND so.[is_ms_shipped] = 0
AND ix.[type] IS NOT NULL --| so we get heaps, and indexed views 
)
SELECT
[Schema], [Object_Name], [Object_Type],
--[Is_Published], [Is_Schema_Published],
[IX_Name],
[IX_Data_Space],
[IX_Move_SQL] = CASE WHEN [IX_Data_Space] <> @Target_Filegroup AND [IX_Type] IN (1,2) THEN CONCAT(
                                                'CREATE ', CASE [Is_Unique] WHEN 1 THEN 'UNIQUE ' END, [IX_Type_Desc], ' INDEX ', QUOTENAME([IX_Name]),
                                                ' ON ', QUOTENAME([Schema]), '.', QUOTENAME([Object_Name]), ' (', [Indexed_Columns_Order], ')',
                                                CASE WHEN [Included_Columns] IS NOT NULL THEN CONCAT(' INCLUDE (', [Included_Columns], ')') END,
                                                CASE WHEN [Has_Filter] = 1 THEN CONCAT(' WHERE ', [Filter]) END,
                                                ' WITH (PAD_INDEX=', CASE [Is_Padded] WHEN 1 THEN 'ON' ELSE 'OFF' END,
                                                ', FILLFACTOR=', CASE WHEN [FF] = 0 THEN '100' ELSE CAST([FF] as varchar(3)) COLLATE DATABASE_DEFAULT END,
                                                ', ALLOW_ROW_LOCKS=', CASE [Allow_Row_Locks] WHEN 1 THEN 'ON' ELSE 'OFF' END,
                                                ', ALLOW_PAGE_LOCKS=', CASE [Allow_Page_Locks] WHEN 1 THEN 'ON' ELSE 'OFF' END,
                                                ', DROP_EXISTING=ON ',')',
                                                ' ON ', QUOTENAME(@Target_Filegroup), ';')

                                                 END COLLATE DATABASE_DEFAULT
FROM [IX]
ORDER BY [Object_Type] ASC, [Schema] ASC , [Object_Name] ASC;
于 2022-01-28T13:58:10.160 に答える