テストデータベースで、私は探しています:
私のワークフローも上記と同じですが、クラスター化を削除する前に、すべての非クラスター化インデックスを無効化しています。
クラスタ化された制約インデックスを削除するには、テーブルをHEAPとして保存する必要があるため、このプロセスが45mの行テーブルにかかる時間は膨大です。制約の低下は1:17:00の間続いており、約31分しかないようです(セッションのSpotlightでの論理読み取りに基づく)。
このワークフローを処理するより効率的な方法はありますか?おそらく、制約インデックスを削除して、HEAPとしてではなく、新しいクラスター化インデックスとして再構築する方法ですか?
ありがとう、ウェス
DDLステートメント:
テーブル構造
CREATE TABLE [dbo].[hist](
[prrowid] [varchar](36) NOT NULL,
[part] [varchar](30) NULL,
[date] [datetime] NULL,
[per_date] [datetime] NULL,
[type] [varchar](80) NULL,
[loc] [varchar](80) NULL,
[loc_begin] [decimal](28, 10) NULL,
[begin_qoh] [decimal](28, 10) NULL,
[qty_req] [decimal](28, 10) NULL,
[qty_chg] [decimal](28, 10) NULL,
[qty_short] [decimal](28, 10) NULL,
[um] [varchar](30) NULL,
[last_date] [datetime] NULL,
[nbr] [varchar](30) NULL,
[so_job] [varchar](80) NULL,
[ship_type] [varchar](30) NULL,
[addr] [varchar](80) NULL,
[rmks] [varchar](80) NULL,
[xdr_acct] [varchar](80) NULL,
[xcr_acct] [varchar](80) NULL,
[mtl_std] [decimal](28, 10) NULL,
[lbr_std] [decimal](28, 10) NULL,
[bdn_std] [decimal](28, 10) NULL,
[price] [decimal](28, 10) NULL,
[trnbr] [int] NULL,
[gl_amt] [decimal](28, 10) NULL,
[xdr_cc] [varchar](30) NULL,
[xcr_cc] [varchar](30) NULL,
[lot] [varchar](80) NULL,
[sub_std] [decimal](28, 10) NULL,
[gl_date] [datetime] NULL,
[qty_loc] [decimal](28, 10) NULL,
[userid] [varchar](80) NULL,
[serial] [varchar](50) NULL,
[effdate] [datetime] NULL,
[prod_line] [varchar](30) NULL,
[xslspsn1] [varchar](80) NULL,
[xslspsn2] [varchar](80) NULL,
[xcr_proj] [varchar](80) NULL,
[xdr_proj] [varchar](80) NULL,
[line] [int] NULL,
[user1] [varchar](80) NULL,
[user2] [varchar](80) NULL,
[curr] [varchar](30) NULL,
[ex_rate] [decimal](28, 10) NULL,
[rev] [varchar](30) NULL,
[time] [int] NULL,
[ovh_std] [decimal](28, 10) NULL,
[site] [varchar](80) NULL,
[status] [varchar](80) NULL,
[grade] [varchar](30) NULL,
[expire] [datetime] NULL,
[assay] [decimal](28, 10) NULL,
[xgl_ref] [varchar](30) NULL,
[_chr01] [varchar](80) NULL,
[_chr02] [varchar](80) NULL,
[_chr03] [varchar](80) NULL,
[_chr04] [varchar](80) NULL,
[_chr05] [varchar](80) NULL,
[_chr06] [varchar](80) NULL,
[_chr07] [varchar](80) NULL,
[_chr08] [varchar](80) NULL,
[_chr09] [varchar](80) NULL,
[_chr10] [varchar](80) NULL,
[_chr11] [varchar](80) NULL,
[_chr12] [varchar](80) NULL,
[_chr13] [varchar](80) NULL,
[_chr14] [varchar](80) NULL,
[_chr15] [varchar](80) NULL,
[_dte01] [datetime] NULL,
[_dte02] [datetime] NULL,
[_dte03] [datetime] NULL,
[_dte04] [datetime] NULL,
[_dte05] [datetime] NULL,
[_dec01] [decimal](28, 10) NULL,
[_dec02] [decimal](28, 10) NULL,
[_dec03] [decimal](28, 10) NULL,
[_dec04] [decimal](28, 10) NULL,
[_dec05] [decimal](28, 10) NULL,
[_log01] [bit] NULL,
[_log02] [bit] NULL,
[ref] [varchar](80) NULL,
[msg] [int] NULL,
[program] [varchar](30) NULL,
[ord_rev] [int] NULL,
[ref_site] [varchar](80) NULL,
[rsn_code] [varchar](80) NULL,
[vend_lot] [varchar](30) NULL,
[vend_date] [datetime] NULL,
[daycode] [varchar](80) NULL,
[for] [varchar](30) NULL,
[slspsn##1] [varchar](82) NULL,
[slspsn##2] [varchar](82) NULL,
[slspsn##3] [varchar](82) NULL,
[slspsn##4] [varchar](82) NULL,
[fsm_type] [varchar](80) NULL,
[upd_isb] [bit] NULL,
[auto_install] [bit] NULL,
[ca_int_type] [varchar](80) NULL,
[covered_amt] [decimal](28, 10) NULL,
[fcg_code] [varchar](80) NULL,
[batch] [varchar](30) NULL,
[fsc_code] [varchar](80) NULL,
[sa_nbr] [varchar](80) NULL,
[sv_code] [varchar](80) NULL,
[eng_area] [varchar](30) NULL,
[sys_prod] [varchar](30) NULL,
[svc_type] [varchar](30) NULL,
[ca_opn_date] [datetime] NULL,
[cprice] [decimal](28, 10) NULL,
[eng_code] [varchar](80) NULL,
[wod_op] [int] NULL,
[enduser] [varchar](80) NULL,
[ship_inv_mov] [varchar](80) NULL,
[ship_date] [datetime] NULL,
[ship_id] [varchar](30) NULL,
[ex_rate2] [decimal](28, 10) NULL,
[ex_ratetype] [varchar](80) NULL,
[exru_seq] [int] NULL,
[promise_date] [datetime] NULL,
[fldchg_cmtindx] [int] NULL,
[SrcPDB] [varchar](12) NULL,
CONSTRAINT [hist_PK] PRIMARY KEY CLUSTERED
(
[prrowid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
現在のインデックス
ALTER TABLE [dbo].[hist] ADD CONSTRAINT [hist_PK] PRIMARY KEY CLUSTERED ( [prrowid] ) WITH (FILLFACTOR=100);
CREATE INDEX [hist##addr_eff] ON [dbo].[hist] ( [addr], [effdate] ) WITH (FILLFACTOR=100);
CREATE INDEX [hist##batch] ON [dbo].[hist] ( [batch] ) WITH (FILLFACTOR=100);
CREATE INDEX [hist##date_trn] ON [dbo].[hist] ( [date], [trnbr] ) WITH (FILLFACTOR=100);
CREATE INDEX [hist##eff_trnbr] ON [dbo].[hist] ( [effdate], [trnbr] ) WITH (FILLFACTOR=100);
CREATE INDEX [hist##nbr_eff] ON [dbo].[hist] ( [nbr], [effdate] ) WITH (FILLFACTOR=100);
CREATE INDEX [hist##part_eff] ON [dbo].[hist] ( [part], [effdate] ) WITH (FILLFACTOR=100);
CREATE INDEX [hist##part_trn] ON [dbo].[hist] ( [part], [trnbr] ) WITH (FILLFACTOR=100);
CREATE INDEX [hist##ref_filter] ON [dbo].[hist] ( [ref] ) WITH (FILLFACTOR=100);
CREATE INDEX [hist##serial] ON [dbo].[hist] ( [serial] ) WITH (FILLFACTOR=100);
CREATE INDEX [hist##trnbr] ON [dbo].[hist] ( [trnbr] ) WITH (FILLFACTOR=100);
CREATE INDEX [hist##type] ON [dbo].[hist] ( [type], [effdate] ) WITH (FILLFACTOR=100);
DESIRED INDEXES
CREATE UNIQUE CLUSTERED INDEX [hist##date_trn_CX] ON [dbo].[hist] ( [date], [trnbr] ) WITH (FILLFACTOR=100);
ALTER TABLE [dbo].[hist] ADD CONSTRAINT [hist_PK] PRIMARY KEY NONCLUSTERED ( [prrowid] ) WITH (FILLFACTOR=100);
CREATE INDEX [hist##addr_eff] ON [dbo].[hist] ( [addr], [effdate] ) WITH (FILLFACTOR=100);
CREATE INDEX [hist##batch] ON [dbo].[hist] ( [batch] ) WITH (FILLFACTOR=100);
CREATE INDEX [hist##eff_trnbr] ON [dbo].[hist] ( [effdate], [trnbr] ) WITH (FILLFACTOR=100);
CREATE INDEX [hist##part_eff] ON [dbo].[hist] ( [part], [effdate] ) WITH (FILLFACTOR=100);
CREATE INDEX [hist##part_trn] ON [dbo].[hist] ( [part], [trnbr] ) WITH (FILLFACTOR=100);
CREATE INDEX [hist##ref_filter] ON [dbo].[hist] ( [ref] ) WITH (FILLFACTOR=100);
CREATE INDEX [hist##serial] ON [dbo].[hist] ( [serial] ) WITH (FILLFACTOR=100);
CREATE INDEX [hist##trnbr] ON [dbo].[hist] ( [trnbr] ) WITH (FILLFACTOR=100);
CREATE INDEX [hist##nbr_eff] ON [dbo].[hist] ( [trnbr], [effdate] ) WITH (FILLFACTOR=100);
CREATE INDEX [hist##trnbr_char] ON [dbo].[hist] ( [trnbr_char] ) WITH (FILLFACTOR=100);
CREATE INDEX [hist##type] ON [dbo].[hist] ( [type], [effdate] ) WITH (FILLFACTOR=100);
CREATE INDEX [hist##vend_lot] ON [dbo].[hist] ( [vend_lot] ) WITH (FILLFACTOR=100);
-注-以下の答えは私にとって完璧に機能しました。ボリュームを追加する必要がありました。新しいドライブに2つ目のファイルグループとデータファイルを作成しました。さらに、別のログファイル。
理想的には次のようなことをするでしょう:
DROP_EXISTING = ON
オプションを設定して、新しい列にクラスター化インデックスを再作成します。これは、テーブルがヒープに変換されるステップをスキップします。残念ながら、SQL Serverのステップ1 可能ではないようです 。
主キーが削除されると、対応するインデックスが削除されます。
さらに、 [〜#〜] bol [〜#〜] は、DROP_EXISTING = ON
を使用して主キーを変更することについて述べています。
インデックスがPRIMARY KEYまたはUNIQUE制約を適用し、インデックス定義がまったく変更されない場合、インデックスは削除され、既存の制約を維持して再作成されます。ただし、インデックス定義が変更されると、ステートメントは失敗します。 PRIMARY KEYまたはUNIQUE制約の定義を変更するには、制約を削除し、新しい定義で制約を追加します。
私の知る限り、できることは、テーブルのコピーを作成してそこにすべてのデータを移動することにより、ヒープ変換を回避することです。クラスタ化インデックスを削除または追加すると、とにかくデータの内部コピーが作成されるため、より多くのスペースが必要になるわけではありません。これをスピードアップするためのヒントをいくつか紹介します。
SELECT INTO
は使用しないでください。これにより、回避しようとしているステップであるヒープにデータがコピーされます。ただし、SELECT INTO
とクラスター化インデックスの作成の両方が、SQL Server 2014での並列処理に適しています。INSERT INTO... SELECT
の場合、最小限のログを取得するには、ターゲットテーブルに対するTABLOCK
ヒントが必要です。SORT_IN_TEMPDB = ON
オプションを使用します。余談ですが、ステップ2の動作を知りたい場合(私はそうでした)、ヒープ変換ステップをスキップする方法を示すサンプルコードを次に示します。
DROP TABLE IF EXISTS dbo.X_NUMBERS_1000000;
CREATE TABLE dbo.X_NUMBERS_1000000 (ID INT NOT NULL, ID2 INT NOT NULL, FILLER VARCHAR(500));
CREATE CLUSTERED INDEX CI_X_NUMBERS_1000000 ON dbo.X_NUMBERS_1000000 (ID);
INSERT INTO dbo.X_NUMBERS_1000000 WITH (TABLOCK)
SELECT TOP (1000000)
ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
, ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
, REPLICATE('Z', 500)
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;
-- option 1
DROP INDEX X_NUMBERS_1000000.CI_X_NUMBERS_1000000;
CREATE CLUSTERED INDEX CI_X_NUMBERS_1000000_2_COL ON dbo.X_NUMBERS_1000000 (ID, ID2);
SQL Server実行時間:CPU時間= 31ミリ秒、経過時間= 51ミリ秒。
SQL Server実行時間:CPU時間= 2406ミリ秒、経過時間= 3484ミリ秒。
-- option 2 (after resetting the table)
CREATE CLUSTERED INDEX CI_X_NUMBERS_1000000 ON dbo.X_NUMBERS_1000000 (ID, ID2)
WITH (DROP_EXISTING = ON);
SQL Server実行時間:CPU時間= 2422ミリ秒、経過時間= 3411ミリ秒。