Cara membuat indeks berkerumun di tabel 100 GB

8

Saya memiliki tabel tumpukan yang membutuhkan sekitar 104 GB ruang disk dengan hampir 3 miliar baris. Saya mencoba membuat indeks berkerumun di tabel ini di WeekEndingDatekolom [ ]. Saya memiliki sekitar 200 gb gratis di file data dan sekitar 280 gb gratis di tempdb.

Saya telah mencoba dua metode berbeda. Pertama adalah membuat indeks langsung di atas meja dengan perintah berikut:

CREATE CLUSTERED INDEX CX_WT_FOLD_HISTORY
ON WT_FOLD_HISTORY (WeekEndingDate ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = ON, 
IGNORE_DUP_KEY = OFF
, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, 
DATA_COMPRESSION = PAGE)

Saya mencoba keduanya dengan SORT_IN_TEMPDB = ONdan OFF. Saat menggunakannya ONmengisi tempdb dan dengan OFFitu mengisi drive data.

Metode lain adalah membuat tabel kosong baru dengan indeks yang diperlukan dan kemudian memasukkan catatan dari tumpukan ke tabel baru. Ini gagal juga setelah mengisi drive data.

Ada saran lain tentang apa yang harus dilakukan. Kebanyakan hal yang saya baca menyatakan bahwa saya akan membutuhkan sekitar 1,2 kali ukuran tabel untuk digunakan sebagai ruang kerja saat membuat indeks. Saya punya cara lebih dari itu dan masih gagal. Setiap saran akan dihargai.

Berikut adalah struktur tabel tumpukan asli saya:

CREATE TABLE [dbo].[WT_FOLD_HISTORY](
[WeekEndingDate] [varchar](50) NULL,
[Division] [varchar](50) NULL,
[Store] [varchar](50) NULL,
[SKUNumber] [varchar](50) NULL,
[UPC] [varchar](50) NULL,
[SalesUnits] [varchar](50) NULL,
[SalesCost] [varchar](50) NULL,
[SalesRetail] [varchar](50) NULL,
[InventoryUnits] [varchar](50) NULL,
[InventoryCost] [varchar](50) NULL,
[InventoryRetail] [varchar](50) NULL,
[OnOrderUnits] [varchar](50) NULL,
[OnOrderCost] [varchar](50) NULL,
[OnOrderRetail] [varchar](50) NULL,
[ReceiptUnits] [varchar](50) NULL,
[ReceiptCost] [varchar](50) NULL,
[ReceiptRetail] [varchar](50) NULL,
[PermanentMarkdowns] [varchar](50) NULL,
[ReturnsToVendor] [varchar](50) NULL,
[POSMarkdowns] [varchar](50) NULL,
[TimeFK] [smallint] NULL,
[LocationFK] [int] NULL,
[ItemFK] [int] NULL
) ON [AcademySports_DataFG1]
pengguna578849
sumber
Saat melakukan pendekatan "tabel baru, pindahkan baris dalam batch", apakah Anda menghapus baris di tabel asli saat memindahkannya? Anda mungkin perlu melakukan beberapa senam tambahan untuk mendapatkan tumpukan untuk melepaskan ruang yang tidak digunakan saat Anda menghapus data.
AMtwo
Mungkin menarik mengapa indeks yang tidak berkerumun tidak dapat diterima dalam kasus ini; [ya, saya menyadari perbedaan / manfaat dari clustered dan non-clustered ... hanya ingin tahu mengapa Anda mengesampingkan indeks non-clustered]; juga, apakah tabel sudah memiliki indeks non-cluster di tempat dan jika demikian berapa banyak ruang yang mereka gunakan? [bertanya-tanya apakah menjatuhkan indeks non-cluster saat ini dapat membebaskan ruang yang cukup untuk membuat indeks cluster?]
markp-fuso
Sudahkah Anda mencoba membuat indeks DATA_COMPRESSION=NONE? Jika berhasil, Anda bisa mengompres sesudahnya.
Dan Guzman
nice question.i google it.and baca ini adalah apa yang mereka katakan dba.stackexchange.com/questions/11956/… atau stackoverflow.com/questions/2309889/… Ini adalah satu-satunya jawaban yang benar.
KumarHarsh
1
Hanya untuk memastikan, dapatkah Anda memasukkan pesan kesalahan yang sebenarnya gagal dengan?
RDFozz

Jawaban:

3

Jika Anda memiliki kebutuhan jangka pendek untuk ruang disk, satu opsi adalah:

  1. Kecilkan tempdb sementara, membebaskan ruang pada drive yang sepertinya aman.
  2. Buat file data sekunder untuk DB tabel di dalam tempdb drive.
  3. Tambahkan indeks berkerumun ke tabel.
  4. Kecilkan file sekunder dengan memigrasikan semua data darinya.
  5. Hapus file sekunder.
  6. Pastikan file tempdb dibiarkan tumbuh ke ukuran semula.
  7. Membangun kembali indeks dalam DB tabel (penghapusan file sekunder akan menyebabkan beberapa fragmentasi).

CATATAN: seperti yang disarankan orang lain, saya hanya akan melakukan ini setelah hal-hal seperti menghapus sementara indeks non-cluster dari tabel yang bersangkutan. Ini khususnya akan memungkinkan penambahan indeks berkerumun untuk berjalan lebih cepat, karena indeks yang tidak berkerumun akan tetap harus dibangun kembali (dengan indeks berkerumun di tempat, kunci indeks digunakan untuk menemukan baris dalam tabel itu sendiri) .

Itu sebenarnya poin lain - seberapa lebar kunci pada indeks berkerumun? Jika Anda memiliki indeks non-cluster, dan kunci pada indeks cluster secara signifikan lebih luas daripada pointer ke tumpukan, maka indeks non-cluster akan mengkonsumsi lebih banyak ruang setelah indeks cluster dibuat.

Jika kunci kluster terdiri dari beberapa kolom, atau bahkan satu kolom besar (katakanlah, varcharkolom dengan panjang rata-rata 25 atau lebih), Anda mungkin ingin mempertimbangkan kunci pengganti sebagai gantinya (biasanya nilai yang meningkat secara monoton, untuk INSERTkinerja terbaik .

RDFozz
sumber
1

Apa yang mengisi ruang Anda adalah mega-sort Anda (Anda mencoba untuk mengurutkan semua 104GB Anda secara keseluruhan), jadi saya pikir itu bisa diselesaikan dengan melakukan pengurutan pada porsi yang lebih kecil. Saya menyarankan Anda untuk membuat tabel berkerumun baru dan memasukkan data dalam potongan kecil seperti ini:

declare @rowcount int = 1;
while @rowcount > 0
begin
  delete top (5000) 
  from your_heap with(tablock) 
      output deleted.field1, ..., deleted.fieldN 
      into new_clustered_table;
  set @rowcount = @@rowcount;
end; 

Dengan cara ini Anda hanya mengurutkan 5.000 baris pada satu waktu dan satu-satunya masalah adalah pemisahan halaman yang tidak dapat dihindari karena Anda tidak membuat sisipan yang disortir. Jadi ketika selesai, new_clustered_table akan terfragmentasi tetapi Anda dapat membangunnya kembali setelah itu.

sepupik
sumber
Ya, Anda benar, saya memperbarui jawaban saya, tetapi itu hanya sebuah ide.
sepupic
0

Hanya tip cepat - pertimbangkan untuk menjatuhkan semua indeks yang tidak berkerumun (jika ada) di tumpukan ini sebelum mencoba membuat Indeks Clustered. Anda dapat membuat skrip non-CI beserta detail kolom sertakannya dan membuatnya lagi nanti dengan definisi tersebut setelah Indeks Clustered berhasil dibuat.

Channdeep Singh
sumber