Ukuran basis data - MDF terlalu besar?

10

Saya memelihara database SQL Server 2005 yang menampung sekitar 2,9Tb data (2 x 1,45Tb - Saya memiliki skema RAW dan skema ANALISIS jadi pada dasarnya dua salinan data dicerna). Model pemulihan SEDERHANA dan .ldfpada 6Gb.

Untuk alasan apa pun, .mdfini adalah 7.5Tb. Sekarang, mungkin hanya ada 2-3 kolom tambahan dalam tabel ANALISA dan tidak banyak NVARCHAR(MAX)kolom yang, dari apa yang saya (mungkin salah paham - perbaiki saya jika saya salah) dapat menyebabkan alokasi ruang tambahan. Itu setelah menyusutkan database sekarang - itu pada ~ 9TB sebelum itu. Adakah pikiran?

Dan, tolong, beri tahu saya jika Anda memiliki pertanyaan tambahan - Saya sangat baru dalam hal administrasi basis data dan upaya pengoptimalan (Saya biasanya tidak melakukan pekerjaan sampingan ini :)).

Terimakasih banyak!

Andrija

Andrija_Bgd
sumber
Terima kasih Marc - bagaimana saya bisa memindahkan pertanyaan ini ke sana atau apakah saya perlu mengirim ulang?
Ceria - karena Anda mungkin bisa menebak, saya baru di sini :)

Jawaban:

11

Dalam perkiraan ukuran Anda, sudahkah Anda memperhitungkan jumlah ruang yang diambil oleh indeks? Juga jika Anda memiliki bidang teks yang ditetapkan sebagai multi-byte ( N[VAR]CHARbukan [VAR]CHAR) dan file input UTF-8 atau polos satu-byte-per-karakter maka itu akan mendorong persyaratan penyimpanan Anda hingga faktor dua. Lebih jauh lagi ingat bahwa jika Anda memiliki kunci / indeks berkerumun di tabel ukuran ini mempengaruhi semua indeks lain di atas meja karena mereka menyertakan nilai kunci berkerumun untuk setiap baris (jadi untuk memberikan contoh ekstrem jika tabel memiliki NCHAR (10 ) kunci di mana INT akan dilakukan dan itu adalah kunci / indeks berkerumun Anda, Anda tidak hanya menggunakan tambahan 16 byte per baris di halaman data, Anda juga membuang 16 byte per baris di setiap indeks lain pada tabel itu ) .

Juga, beberapa ruang akan dialokasikan tetapi tidak digunakan, baik karena mesin DB telah meninggalkan beberapa ruang yang dialokasikan setelah dihapus sehingga dapat digunakan kembali dengan cepat untuk data baru dalam tabel itu atau karena pola memasukkan dan menghapus telah meninggalkan banyak halaman hanya bagian penuh.

Anda dapat menjalankan:

SELECT o.name
     , SUM(ps.reserved_page_count)/128.0 AS ReservedMB
     , SUM(ps.used_page_count)/128.0 AS UsedMB
     , SUM(ps.reserved_page_count-ps.used_page_count)/128.0 AS DiffMB
FROM sys.objects o  
JOIN sys.dm_db_partition_stats ps ON o.object_id = ps.object_id  
WHERE OBJECTPROPERTYEX(o.object_id, 'IsMSShipped') = 0  
GROUP BY o.name  
ORDER BY SUM(ps.reserved_page_count) DESC

untuk melihat sekilas tabel apa yang mengambil ruang.

Juga EXEC sp_spaceusedberjalan di dalam DB yang akan mengembalikan dua set hasil. Yang pertama daftar total ruang yang dialokasikan dalam sistem file untuk file data dan berapa banyak yang tidak dialokasikan, yang kedua daftar berapa banyak ruang yang dialokasikan digunakan untuk halaman data, untuk halaman indeks, atau saat ini tidak digunakan.

sp_spaceused akan mengembalikan ruang yang digunakan oleh objek yang diberikan juga, sehingga Anda dapat mengulang ini untuk membangun tabel untuk analisis:

-- TEMP TABLES FOR ANALYSIS
CREATE TABLE #tTables (sName NVARCHAR(MAX), iRows BIGINT, iReservedKB BIGINT, iDataKB BIGINT, iIndexKB BIGINT, iUnusedKB BIGINT)
CREATE TABLE #tTmp (sName NVARCHAR(MAX), iRows BIGINT, sReservedKB NVARCHAR(MAX), sDataKB NVARCHAR(MAX), sIndexKB NVARCHAR(MAX), sUnusedKB NVARCHAR(MAX))
-- COLLECT SPACE USE PER TABLE
EXEC sp_msforeachtable 'INSERT #tTmp EXEC sp_spaceused [?];'
-- CONVERT NUMBER-AS-TEXT COLUMNS TO NUMBER TYPES FOR EASIER ANALYSIS
INSERT #tTables SELECT sName, iRows
                     , CAST(REPLACE(sReservedKB, ' KB', '') AS BIGINT)
                     , CAST(REPLACE(sDataKB    , ' KB', '') AS BIGINT)
                     , CAST(REPLACE(sIndexKB   , ' KB', '') AS BIGINT)
                     , CAST(REPLACE(sUnusedKB  , ' KB', '') AS BIGINT) 
                FROM #tTmp
DROP TABLE #tTmp 
-- DO SOME ANALYSIS 
SELECT sName='TOTALS', iRows=SUM(iRows), iReservedKB=SUM(iReservedKB), iDataKB=SUM(iDataKB),  iIndexKB=SUM(iIndexKB), iUnusedKB=SUM(iUnusedKB) FROM #tTables ORDER BY sName
SELECT * FROM #tTables ORDER BY iReservedKB DESC
-- CLEAN UP
DROP TABLE #tTables

Kode di atas akan menampilkan semua ukuran tabel dalam satu daftar, ditambah satu baris untuk total. Jika perlu Anda dapat menggunakan berbagai tampilan sistem (seperti sys.objectsdan sys.dm_db_partition_statsdigunakan dalam permintaan pertama di atas, lihat http://technet.microsoft.com/en-us/library/ms177862.aspx untuk lebih jelasnya) untuk mendapatkan detail lebih lanjut seperti ruang yang digunakan oleh setiap indeks.


Ada tiga kelas ruang yang tidak digunakan dalam file data:

  1. Apa yang tidak dialokasikan untuk apa pun (ini menunjukkan di hasil pertama dari sp_spaceusedtanpa objek yang ditentukan)
  2. Apa yang dialokasikan untuk objek (dilindungi undang-undang) tetapi saat ini tidak digunakan (ini menunjukkan dalam "tidak digunakan" dalam sp_spaceusedoutput.
  3. Itu terkunci di halaman yang digunakan sebagian (ini akan terlihat untuk digunakan karena semuanya dialokasikan dalam potongan halaman tunggal, satu halaman menjadi 8.192 byte panjang). Ini lebih sulit untuk dideteksi / dihitung. Ini karena campuran dua faktor:
    • Halaman terpisah. Ketika data ditambahkan, Anda sering berakhir dengan bagian halaman yang kosong (mesin penyimpanan selalu dapat menormalkan isi halaman, tetapi ini akan sangat tidak efisien), dan karena baris dihapus, konten halaman tidak secara otomatis dikemas (sekali lagi mungkin, tetapi tambahan Beban I / O umumnya jauh dari layak).
    • Mesin penyimpanan tidak akan membagi satu baris menjadi beberapa halaman (ini bersama dengan ukuran halaman dari mana batas 8.119 byte per baris berasal dari). Jika baris Anda berukuran tetap dan masing-masing mengambil 1.100 byte, maka Anda akan "membuang" setidaknya 492 byte dari setiap blok data yang dialokasikan ke tabel itu (7 baris mengambil 7.700 byte dan yang ke-8 tidak cocok sehingga sisanya akan menang ' t digunakan). Semakin lebar baris, semakin buruk hal ini. Tabel / indeks dengan baris panjang variabel (yang jauh lebih umum daripada yang benar-benar panjang tetap) umumnya lebih baik (tetapi kurang mudah untuk menghitung masalah untuk).
      Peringatan lain di sini adalah benda besar ( TEXTkolom,[N]VARCHAR(MAX) nilai-nilai di atas ukuran tertentu dan seterusnya) karena mereka ditempatkan di luar halaman, hanya mengambil 8 byte di data baris utama untuk menahan pointer ke data di tempat lain) sehingga dapat mematahkan 8.192 byte-per-baris-batas.

tl; dr: Memperkirakan ukuran basis data yang diharapkan bisa menjadi jauh lebih banyak terlibat daripada yang biasanya diasumsikan pada awalnya.

David Spillett
sumber
David - terima kasih banyak atas tanggapan terperinci! Saya sedang menganalisis db sekarang dan baik tanggapan Anda dan Kenneth sangat membantu dalam pemahaman saya tentang faktor-faktor yang mempengaruhi ukuran database. Saya selalu peduli dengan efisiensi (baik dalam hal konsumsi data dan penggunaan data) dan informasi yang Anda berikan telah sangat berharga!
Andrija_Bgd
6

Coba jalankan sp_spaceuseddi database Anda. Sebagai contoh ia mengembalikan:

reserved           data               index_size         unused
------------------ ------------------ ------------------ ------------------
6032 KB            2624 KB            1664 KB            1744 KB

Untuk menjalankannya pada database, hanya USEdatabase kemudian jalankan sp_spaceused.

Jika masih menunjukkan banyak ruang yang tidak digunakan, Anda dapat mencoba menyusut lagi. Terkadang saya merasa perlu beberapa kali percobaan. Juga kadang-kadang saya menemukan itu bekerja lebih baik untuk mengecilkan file individual daripada database secara keseluruhan. Namun apa yang Anda temukan adalah bahwa Anda memiliki data 2,9TB dan indeks 4 + Tb lainnya dalam hal 7.5TB cukup masuk akal. Jika Anda ingin merasakan jumlah ruang (data & indeks) dari masing-masing tabel maka Anda dapat berjalan sp_spaceuseddi level tabel juga. Anda bisa menjalankannya di semua tabel dalam database dengan menggunakan perintah berikut:

EXEC sp_msforeachtable 'EXEC sp_spaceused [?];'

Meskipun sp_msforeachtable peringatan yang adil tidak berdokumen, tidak didukung, dan telah diketahui kehilangan tabel. Di sisi lain, saya sendiri cukup beruntung.

Semua itu dikatakan database Anda HARUS memiliki persentase ruang bebas tertentu tergantung pada pertumbuhan yang Anda harapkan. Pada dasarnya Anda ingin memastikan bahwa Anda memiliki ruang untuk pertumbuhan mulai dari 6 bulan hingga beberapa tahun. Anda juga akan ingin memeriksa autogrowthpengaturan Anda untuk memastikan mereka sesuai dengan situasi Anda. Khususnya mengingat ukuran basis data Anda, Anda TIDAK ingin menggunakan% autogrowth.

Kenneth Fisher
sumber
Terima kasih! Saya menggunakan sp_spaceused dan kelihatannya data aktual sebenarnya mengambil jumlah ruang yang ditunjukkan, seaneh yang mungkin terdengar bagi saya mengingat ukuran sebenarnya dari file datar yang dimuat ... Indeks kecil (Aku belum ' t membuat yang tambahan karena mereka akan lebih menjadi penghalang daripada bantuan dalam kasus saya) jadi saya kira itu hanya tabel aktual yang besar ... Terima kasih banyak atas bantuan Anda!
Andrija_Bgd
Database memang memakan lebih banyak ruang daripada file datar. Ada sejumlah overhead untuk struktur baris dan tabel dan sejumlah pemborosan karena struktur halaman.
Kenneth Fisher
-1

Menggunakan SQL Management Studio, 1. Klik kanan pada Database Kemudian 2. Klik Tugas-> Kecilkan -> File

Anda akan melihat dialog yang menunjukkan: a. Ruang yang Saat Ini Dialokasi b. Tersedia Ruang Kosong + (% gratis)

Jika% Gratis Anda lebih dari 50%, Anda mungkin mempertimbangkan untuk menyusutkan file. Saya telah melihat hit ini sebanyak 90%. Jika saya memutuskan untuk mengecilkan file saya biasanya mengaturnya ke 2 atau 3 gigs lebih dari ruang yang dialokasikan saat ini. Sebagian besar database saya kurang dari 50 pertunjukan. Jadi jika Anda memiliki file yang jauh lebih besar maka Anda mungkin membuatnya 10 gigs. Saya biasanya hanya khawatir tentang menyusut jika saya akan memindahkan database ke server lain, Anda dapat membaca semua tentang masalah menyusut pada halaman sql apa pun.

Clark Vera
sumber