Apakah kolom kosong membutuhkan ruang dalam tabel?


20

Saya punya tabel yang berisi informasi yang sangat mendasar. Hanya judul dan beberapa bidang tanggal. Ada satu bidang yang disebut komentar yang varchar (4000) Sebagian besar waktu kami biarkan kosong, tetapi beberapa kali akan memasukkan sejumlah besar data di sini. Apakah ini desain yang sangat buruk? Atau ini hanya sedikit tidak efisien?

Saya akan menganggap membuat tabel terpisah untuk kolom ini akan lebih baik.

Catatan: ini adalah sql server 2008

masukkan deskripsi gambar di sini


Terima kasih atas tanggapan Anda, semuanya! Saya memutuskan untuk membuatnya tetap sederhana dan menyimpan kolom di meja dan tidak memasukkannya ke meja lain. Namun saya menggunakan fitur SPARSE di SQL 2008 sehingga bidang tidak menggunakan ruang apa pun.

2
Hanya ingin tahu, apa itu "sebagian besar waktu"? Berapa total baris, dan berapa persentase yang memiliki nilai di sini? Hanya ingin tahu apakah Anda berencana untuk melakukan perbandingan ruang / kinerja menggunakan SPARSEdan tidak menggunakan SPARSE...
Aaron Bertrand

Jawaban:


9

Untuk kinerja yang lebih mudah diprediksi (dan untuk menghindari variasi baris yang tinggi per halaman), saya akan cenderung untuk menyimpan data ini dalam tabel terkait - terutama jika hanya diisi sebagian kecil dari waktu, dan terutama jika hanya diambil dalam beberapa pertanyaan. Baris di mana nilai ini NULLberkontribusi pada overhead ruang, tetapi ini minimal. Yang lebih penting adalah bagaimana satu halaman hanya dapat memuat dua baris dan halaman berikutnya dapat memuat 500 baris - ini benar-benar dapat memengaruhi statistik dan Anda mungkin lebih baik membagi ini sehingga disimpan secara terpisah dan tidak memengaruhi semua operasi Anda pada tabel inti.


12

Dibutuhkan ruang minimal saat tidak digunakan

  • satu bit dalam bitmap NULL
  • panjang dua byte (yang akan menjadi nol bila NULL)

Biaya overhead minimal dan optimisasi akan prematur.

Sampai Anda tahu Anda memiliki masalah, simpan saja di satu meja. Anda mematahkan KISS dengan memperkenalkan gabungan luar dan menambahkan overhead dalam meminta data.

Lihat /programming/3793022/how-to-come-to-limits-of-8060-bytes-per-row-and-8000-per-varchar-nvarchar-valu/3793265#3793265 untuk informasi lebih lanjut


10

Saya pikir tabel terpisah akan lebih baik untuk meningkatkan kepadatan halaman dan mengurangi fragmentasi, terutama jika Anda tidak selalu mengisi bidang itu.

  • Halaman data menampung sekitar 8000 byte
  • Anda memiliki beberapa baris dengan mengatakan 100 byte dan beberapa baris dengan lebih dari 4000 byte
  • Baris-baris panjang itu akan berada di halaman sendiri, dan sisa halaman itu adalah ruang "terbuang" yang digunakan oleh DB Anda tetapi kemungkinan tidak akan pernah menyimpan data
  • Jika Anda menambahkan data ke bidang panjang itu untuk catatan di sebagian besar halaman penuh, itu kemungkinan akan membanjiri halaman dan menghasilkan pointer ke halaman dengan sisa catatan

Semua halaman dan petunjuk kosong ini menyebabkan kinerja yang buruk. Normalisasikan bidang itu jika Anda bisa.


4

Pertanyaan ini terlihat sangat mirip: apakah kolom kosong tambahan mempengaruhi ukuran tabel sql secara signifikan?

Sepertinya jawabannya adalah ya memang tidak memakan tempat, tetapi ada algoritma kompresi untuk kolom dengan banyak nilai nol.

Sejauh desain, saya pikir memiliki tabel eksternal yang terhubung dengan ini akan menjadi desain yang lebih bersih. Memiliki kolom dengan sering nilai-nilai nol mempersulit para pengguna database karena mereka dapat secara tidak sengaja menggunakan nilai nol jika mereka tidak hati-hati. Oleh karena itu, kode yang menggunakan database harus berisi pemeriksaan kesalahan dan itu hanya jelek dari sana.


2
Secara eksplisit, algoritma kompresi hanya berlaku untuk kolom yang secara eksplisit didefinisikan sebagai SPARSE, bukan hanya "kolom dengan banyak nilai nol."
Aaron Bertrand

2

Anda akan baik-baik saja - itu sudah menjadi kolom varchar, jadi itu hanya menggunakan ruang ketika berisi data. Jika Anda memiliki banyak kolom ukuran tetap nullable seperti int, Anda mungkin memiliki masalah penggunaan ruang.

Sejauh menaruhnya di meja lain, aku tidak akan repot. Anda juga bisa melihat menggunakan varchar (maks) dan opsi in / out of row. Sekali lagi, mungkin terlalu dini.


1
Optimalisasi prematur seringkali bisa menjadi masalah nyata, tetapi itu tergantung pada biaya refactoring nanti. Jika Anda tahu hari ini bahwa hanya 1% dari baris Anda akan memiliki data di kolom ini, dan Anda mengharapkan tabel bertambah besar dari waktu ke waktu, berapakah nilai dalam mempertahankan data di tabel saat ini hanya akan mengalami konsekuensi saat Anda menskala? Saya semua menghindari optimasi prematur, tetapi ada satu titik ketika saya menimbang efek jangka panjang dari melakukannya.
Aaron Bertrand

@ Harun Bertrand Setuju. Orang-orang mengajukan pertanyaan kinerja di sini dan mudah untuk berasumsi bahwa mereka mungkin memiliki aplikasi yang jutaan baris dan mereka perlu menggunakan setiap senjata di toolkit dan mengingat semua itu. Di sisi lain, kadang-kadang pengguna tampaknya berada di awal kurva belajar dan sulit untuk meminta mereka berkomitmen waktu untuk sesuatu yang mungkin lebih rendah pada prioritas mereka. Juga, dengan varchar (maks), Anda secara efektif dapat menjentikkan sakelar untuk mulai menyimpan di luar baris. Saya pikir jawaban sebenarnya di sini adalah "Anda belum benar-benar memberi kami informasi yang cukup untuk memberikan jawaban yang pasti".
Cade Roux
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.