Cara mempartisi tabel non-partisi yang ada


22

Saya memiliki tabel yang sudah ada dengan data:

dbo.Test (col1,col2,col3....) ON [PRIMARY]

Saya perlu mengubah tabel ini untuk dipartisi seperti ini:

dbo.Test(col1,col2,col3....) ON Ps_Date(Col2)

Bagaimana saya bisa mencapai ini tanpa menjatuhkan dan membuat ulang tabel?

Jawaban:


23

Untuk mempartisi tabel, Anda dapat mengikuti langkah-langkah singkat di bawah ini:

  • pertama buat fungsi partisi dan skema partisi
  • Setelah itu Anda bisa mempartisi tabel.
  • JIKA tabel Anda memiliki indeks berkerumun, maka Anda perlu menjatuhkan dan membuatnya kembali di partisi yang tepat atau Anda dapat menggunakan DROP_EXISTINGklausa untuk membuat kembali indeks berkerumun.
  • Jika tabel Anda tidak memiliki indeks berkerumun, maka Anda bisa membuatnya di partisi yang tepat menggunakan skema partisi.
  • Edisi Enterprise juga memiliki fleksibilitas dalam menggunakan ONLINE=ONopsi pernyataan CREATE INDEX untuk meminimalkan waktu henti untuk aplikasi Anda. Perhatikan bahwa Anda akan melihat penurunan kinerja saat indeks sedang dibangun kembali menggunakan opsi ONLINE.

Untuk mengotomatiskan partisi, Anda dapat menggunakan utilitas SQL Server Partition Management atau SQL Server Partitioned Table Framework yang tersedia di codeplex juga.

Beberapa sumber yang baik:


53

Anda tidak menentukan apakah tabel Anda memiliki indeks berkerumun atau tidak, jadi mari kita telusuri semua opsi.

Saya akan menggunakan contoh fungsi partisi, skema partisi, dan tabel ini:

CREATE PARTITION FUNCTION pf1(INT) AS RANGE LEFT FOR VALUES(10,20,30,40);
GO
CREATE PARTITION SCHEME ps1 AS PARTITION pf1 ALL TO ([PRIMARY])
GO
CREATE TABLE dbo.pt(pc INT NOT NULL, id INT NOT NULL) ON [PRIMARY];
GO

1. Tabel Anda memiliki indeks berkerumun yang tidak dibuat oleh kendala.

Ini adalah kasus termudah. Anda bisa menggunakan CREATE INDEXpernyataan dengan DROP_EXISTINGklausa untuk memindahkan tabel ke skema partisi.

Asumsikan untuk contoh bahwa indeks berkerumun ini telah dibuat:

CREATE UNIQUE CLUSTERED INDEX ptc ON dbo.pt(Id) ON [PRIMARY];

Untuk mempartisi tabel ini, indeks berkerumun telah menyertakan kolom partisi (pt dalam kasus kami) sebagai bagian dari kunci. Pernyataan ini mengubah indeks berkerumun untuk memasukkan kolom partisi dan mempartisinya pada saat yang sama:

CREATE UNIQUE CLUSTERED INDEX ptc ON dbo.pt(pc, Id) WITH(DROP_EXISTING = ON)ON ps1(pc) ;

The DROP_Existingklausul secara otomatis menghapus indeks yang ada sebelum membuat yang baru. Ini lebih disukai daripada yang terpisah DROP INDEXkarena menyebabkan indeks yang tidak terkecil dibangun kembali hanya sekali.

2. Tabel Anda memiliki indeks berkerumun yang merupakan bagian dari PRIMARY KEYatau UNIQUEkendala dan berisi kolom partisi sebagai bagian dari kunci

Yang ini masih mudah dan sangat mirip dengan yang sebelumnya.

Asumsikan PRIMARY KEYkendala ini telah dibuat di atas meja:

ALTER TABLE dbo.pt ADD CONSTRAINT ptc PRIMARY KEY CLUSTERED (pc, Id) ON [PRIMARY];

Sekarang Anda bisa menjalankan skrip penciptaan ulang yang sama dengan yang kami gunakan di 1:

CREATE UNIQUE CLUSTERED INDEX ptc ON dbo.pt(pc, Id) WITH(DROP_EXISTING = ON)ON ps1(pc) ;

3. Tabel memiliki indeks berkerumun yang tidak termasuk kolom partisi tetapi dibuat sebagai bagian dari PRIMARY KEYatau UNIQUEkendala

Keberuntungan yang cukup. Anda tidak dapat mengubah definisi PRIMARY KEYatau UNIQUEkendala setelah fakta. Satu-satunya pilihan Anda adalah dengan menjatuhkan batasan dan kemudian membuatnya kembali termasuk kolom partisi atau membuat indeks berkerumun independen dari kendala yang mencakup kolom partisi. Dalam kasus kedua Anda dapat membuat kembali kendala NONCLUSTEREDtanpa menyertakan kolom partisi. Karena sekarang batasan ini tidak selaras (artinya indeks pendukungnya tidak dipartisi) Anda harus menentukan tempat untuk meletakkannya di disk.

Asumsikan tabel memiliki kunci utama seperti ini:

ALTER TABLE dbo.pt ADD CONSTRAINT ptc PRIMARY KEY CLUSTERED (Id) ON [PRIMARY];

Untuk mempartisi tabel ini, Anda harus melepaskan kendala terlebih dahulu:

ALTER TABLE dbo.pt DROP CONSTRAINT ptc;

Maka Anda perlu membuat indeks berkerumun dipartisi:

CREATE UNIQUE CLUSTERED INDEX ptci ON dbo.pt(pc, Id) ON ps1(pc) ;

Jika Anda memilih untuk membuat kembali PRIMARY KEYkendala yang tidak selaras, Anda dapat melakukannya seperti ini:

ALTER TABLE dbo.pt ADD CONSTRAINT ptc PRIMARY KEY NONCLUSTERED (Id) ON [PRIMARY];

4. Tabel Anda tidak memiliki indeks berkerumun

Dalam kasus ini, direkomendasikan dalam kebanyakan kasus untuk hanya membuat indeks berkerumun untuk membuat partisi. Anda dapat menggunakan pernyataan indeks buat yang sebelumnya terlihat untuk itu:

CREATE UNIQUE CLUSTERED INDEX ptci ON dbo.pt(pc, Id) ON ps1(pc) ;

Namun, jika Anda memiliki alasan yang baik untuk tidak membuat indeks berkerumun Anda bisa lolos dengan pendekatan dua langkah berikut. Sayangnya tidak ada cara langsung untuk melakukan perubahan ini.

Asumsikan tabel Anda tidak memiliki indeks berkerumun. Untuk mempartisi tabel, Anda harus terlebih dahulu membuat CLUSTERED UNIQUEbatasan. (Anda juga bisa menggunakan CLUSTERED PRIMARY KEYbatasan). Jika Anda memiliki kombinasi kolom yang unik itu adalah langkah sederhana:

ALTER TABLE dbo.pt ADD CONSTRAINT ptc UNIQUE CLUSTERED(pc,id);

Setelah batasan dibuat, Anda dapat menjatuhkannya lagi dan "memindahkan" tabel ke skema partisi baru secara bersamaan:

ALTER TABLE dbo.pt DROP CONSTRAINT ptc WITH(MOVE TO ps1(pc));

Jika Anda tidak memiliki kombinasi kolom yang unik, Anda kurang beruntung. Dalam hal ini, satu-satunya pilihan Anda adalah menambahkan kolom baru dan mengisinya dengan nilai-nilai unik. Jika tabelnya cukup kecil Anda bisa melakukan sesuatu seperti ini:

ALTER TABLE dbo.pt ADD tmp_id INT IDENTITY(1,1);

Namun, itu akan mengambil kunci tabel eksklusif sampai semua baris dinilai. Tergantung pada ukuran tabel ini bisa cukup lama. Setelah kolom itu dibuat, ikuti dua langkah di atas untuk pertama-tama membuat UNIQUEbatasan dan kemudian langsung drop lagi. Setelah itu Anda juga bisa menjatuhkan kolom lagi. Semua langkah ini cukup mengganggu, jadi Anda mungkin lebih baik hanya membuat indeks berkerumun di atas meja. Itu bahkan tidak harus unik.


Jika Anda memiliki Edisi Perusahaan, Anda dapat menggunakan WITH(ONLINE=ON)klausa pada sebagian besar pernyataan di atas. Itu akan membuat meja Anda tersedia untuk koneksi lain. Namun, akan ada dampak kinerja selama waktu itu.


1
Luar biasa, Sabastian! Hanya sangat baik! Untuk menambah # 3 di atas ... jika Anda ingin menggunakan SWITCH masuk atau keluar, semua indeks harus disejajarkan. Membuat PK non-clustered, non-aligned tidak akan memungkinkan Anda untuk melakukan SWITCH kecuali Anda mengambil langkah-langkah untuk menjatuhkan indeks terlebih dahulu, melakukan SWITCH (apa pun arahnya), dan membangun kembali indeks. Itu sangat sering masih lebih cepat daripada melakukan yang setara dengan penghapusan dan, tentu saja, jika Anda tidak perlu menggunakan SWITCH, tidak akan menjadi masalah.
Jeff Moden
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.