Dalam SQL Server 2005, apakah ada kerugian untuk membuat semua bidang karakter nvarchar (MAX) daripada menentukan panjang secara eksplisit, misalnya nvarchar (255)? (Terlepas dari yang jelas bahwa Anda tidak dapat membatasi panjang bidang di tingkat basis data)
sql
sql-server
sql-server-2005
stucampbell
sumber
sumber
Jawaban:
Pertanyaan yang sama ditanyakan di Forum MSDN:
Dari pos asli (lebih banyak informasi di sana):
sumber
N/VARCHAR(MAX)
" karena ada pemrosesan tambahan "hanya jika ukurannya melebihi 8000". Dengan demikian, Anda hanya perlu mengeluarkan biaya saat diperlukan , dan basis data Anda tidak terlalu ketat . Apakah saya salah membaca ini? Sepertinya Anda hampir selalu menginginkannyaN/VARCHAR(MAX)
daripadaN/VARCHAR(1-8000)
...sp_tableoptions
: msdn.microsoft.com/en-us/library/ms173530.aspx . Tipe VARCHAR (255) juga dapat didorong keluar dari baris, 'overhead' yang disebutkan mungkin persis sama untuk MAX dan 255. Tipe ini membandingkan tipe MAX dengan tipe TEXT, ketika mereka berbeda saat mendapat (sama sekali berbeda API untuk memanipulasi, penyimpanan yang berbeda dll). Gagal menyebutkan perbedaan yang sebenarnya: tidak ada indeks, tidak ada operasi online pada tipe MAXItu pertanyaan yang wajar dan dia menyatakan selain dari yang sudah jelas ...
Kerugian dapat mencakup:
Implikasi kinerja. Optimizer kueri menggunakan ukuran bidang untuk menentukan rencana exectution paling efisien
"1. Alokasi ruang dalam ekstensi dan halaman-halaman database fleksibel. Dengan demikian ketika menambahkan informasi ke bidang menggunakan pembaruan, database Anda harus membuat pointer jika data baru lebih panjang dari yang dimasukkan sebelumnya. Ini file database akan menjadi terfragmentasi = kinerja yang lebih rendah di hampir semua hal, mulai dari indeks hingga dihapus, diperbarui, dan disisipkan. " http://sqlblogcasts.com/blogs/simons/archive/2006/02/28/Why-use-anything-but-varchar_2800_max_2900_.aspx
Implikasi integrasi - sulit bagi sistem lain untuk mengetahui bagaimana mengintegrasikan dengan database Anda Pertumbuhan data yang tidak dapat diprediksi Kemungkinan masalah keamanan misalnya Anda dapat membuat crash sistem dengan mengambil semua ruang disk
Ada artikel bagus di sini: http://searchsqlserver.techtarget.com/tip/1,289483,sid87_gci1098157,00.html
sumber
varchar(max)
.Berdasarkan tautan yang disediakan dalam jawaban yang diterima, tampak bahwa:
100 karakter yang disimpan dalam suatu
nvarchar(MAX)
bidang akan disimpan tidak berbeda dengan 100 karakter dalam suatunvarchar(100)
bidang - data akan disimpan sebaris dan Anda tidak akan memiliki overhead membaca dan menulis data 'di luar baris'. Jadi tidak perlu khawatir.Jika ukurannya lebih besar dari 4000 data akan disimpan 'di luar baris' secara otomatis, yang Anda inginkan. Jadi tidak ada kekhawatiran di sana.
Namun...
nvarchar(MAX)
kolom. Anda dapat menggunakan pengindeksan teks lengkap, tetapi Anda tidak dapat membuat indeks pada kolom untuk meningkatkan kinerja kueri. Bagi saya, ini segel kesepakatan ... itu adalah kerugian yang pasti untuk selalu menggunakan nvarchar (MAX).Kesimpulan:
Jika Anda menginginkan semacam "panjang string universal" di seluruh basis data Anda, yang dapat diindeks dan yang tidak akan membuang ruang dan waktu akses, maka Anda dapat menggunakannya
nvarchar(4000)
.sumber
nvarchar(max)
sepanjang waktu - sepertistring
di C #? - tetapi poin 3) (masalah indeks) memberikan jawaban.nvarchar(4000)
Terkadang Anda ingin tipe data untuk menerapkan beberapa pengertian pada data di dalamnya.
Katakan misalnya Anda memiliki kolom yang benar-benar tidak boleh lebih dari, katakanlah, 20 karakter. Jika Anda mendefinisikan kolom itu sebagai VARCHAR (MAX), beberapa aplikasi jahat bisa memasukkan string panjang ke dalamnya dan Anda tidak akan pernah tahu, atau punya cara untuk mencegahnya.
Kali berikutnya aplikasi Anda menggunakan string itu, dengan asumsi bahwa panjang string itu sederhana dan masuk akal untuk domain yang diwakilinya, Anda akan mengalami hasil yang tidak dapat diprediksi dan membingungkan.
sumber
Saya memeriksa beberapa artikel dan menemukan skrip uji yang berguna dari ini: http://www.sqlservercentral.com/Forums/Topic1480639-1292-1.aspx Kemudian mengubahnya untuk membandingkan antara NVARCHAR (10) vs NVARCHAR (4000) vs NVARCHAR (MAX) ) dan saya tidak menemukan perbedaan kecepatan saat menggunakan angka yang ditentukan tetapi saat menggunakan MAX. Anda dapat menguji sendiri. Semoga ini bisa membantu.
sumber
Anggap saja sebagai tingkat keamanan lain. Anda bisa mendesain meja Anda tanpa hubungan kunci asing - benar-benar valid - dan memastikan keberadaan entitas terkait sepenuhnya di lapisan bisnis. Namun, kunci asing dianggap praktik desain yang baik karena mereka menambah tingkat kendala lain jika terjadi sesuatu yang kacau pada lapisan bisnis. Hal yang sama berlaku untuk batasan ukuran bidang dan tidak menggunakan varchar MAX.
sumber
Alasan TIDAK untuk menggunakan bidang max atau teks adalah bahwa Anda tidak dapat melakukan pembangunan kembali indeks online yaitu MEMBANGUN KEMBALI DENGAN ONLINE = HIDUP bahkan dengan SQL Server Enterprise Edition.
sumber
Satu-satunya masalah yang saya temukan adalah bahwa kami mengembangkan aplikasi kami pada SQL Server 2005, dan dalam satu contoh, kami harus mendukung SQL Server 2000. Saya baru belajar, betapa sulitnya SQL Server 2000 tidak menyukai opsi MAX untuk varchar atau nvarchar.
sumber
Gagasan buruk ketika Anda tahu bidangnya akan berada dalam kisaran set- 5 hingga 10 karakter misalnya. Saya pikir saya hanya akan menggunakan maks jika saya tidak yakin berapa panjangnya. Misalnya nomor telepon tidak akan pernah lebih dari jumlah karakter tertentu.
Bisakah Anda dengan jujur mengatakan bahwa Anda tidak yakin tentang persyaratan panjang perkiraan untuk setiap bidang di tabel Anda?
Saya mengerti maksud Anda - ada beberapa bidang yang saya pasti akan pertimbangkan untuk menggunakan varchar (maks).
Menariknya, dokumen MSDN merangkumnya dengan cukup baik:
Ada diskusi menarik tentang masalah ini di sini .
sumber
Tugas dari database adalah menyimpan data sehingga dapat digunakan oleh perusahaan. Bagian dari pembuatan data yang bermanfaat adalah memastikan bahwa data itu bermakna. Mengizinkan seseorang untuk memasukkan jumlah karakter yang tidak terbatas untuk nama depan mereka tidak menjamin data yang bermakna.
Membangun batasan-batasan ini ke dalam lapisan bisnis adalah ide yang bagus, tetapi itu tidak memastikan bahwa database akan tetap utuh. Satu-satunya cara untuk menjamin bahwa aturan data tidak dilanggar adalah dengan menegakkannya pada tingkat serendah mungkin dalam database.
sumber
Satu masalah adalah bahwa jika Anda harus bekerja dengan beberapa versi SQL Server, MAX tidak akan selalu berfungsi. Jadi, jika Anda bekerja dengan warisan DB atau situasi lain yang melibatkan banyak versi, Anda sebaiknya berhati-hati.
sumber
Seperti yang ditunjukkan di atas, ini terutama merupakan pertukaran antara penyimpanan dan kinerja. Setidaknya dalam banyak kasus.
Namun, setidaknya ada satu faktor lain yang harus dipertimbangkan ketika memilih n / varchar (Max) daripada n / varchar (n). Apakah data akan diindeks (seperti, misalnya, nama belakang)? Karena definisi MAX dianggap sebagai LOB, maka apa pun yang didefinisikan sebagai MAX tidak tersedia untuk pengindeksan. dan tanpa indeks, pencarian apa pun yang melibatkan data sebagai predikat dalam klausa WHERE akan dipaksa ke pemindaian Tabel Penuh, yang merupakan kinerja terburuk yang bisa Anda dapatkan untuk pencarian data.
sumber
1) Server SQL harus menggunakan lebih banyak sumber daya (memori yang dialokasikan dan waktu cpu) ketika berhadapan dengan nvarchar (max) vs nvarchar (n) di mana n adalah angka khusus untuk bidang tersebut.
2) Apa artinya ini dalam hal kinerja?
Pada SQL Server 2005, saya menanyakan 13.000 baris data dari tabel dengan 15 nvarchar (maks) kolom. Saya menghitung waktu kueri berulang kali dan kemudian mengubah kolom menjadi nvarchar (255) atau kurang.
Permintaan sebelum optimasi rata-rata pada 2,0858 detik. Permintaan setelah perubahan kembali dalam rata-rata 1,90 detik. Itu sekitar 184 milidetik perbaikan untuk kueri pemilihan * dasar. Itu adalah peningkatan 8,8%.
3) Hasil saya sesuai dengan beberapa artikel lain yang menunjukkan bahwa ada perbedaan kinerja. Bergantung pada basis data dan kueri Anda, persentase peningkatan dapat bervariasi. Jika Anda tidak memiliki banyak pengguna bersamaan atau sangat banyak catatan, maka perbedaan kinerja tidak akan menjadi masalah bagi Anda. Namun, perbedaan kinerja akan meningkat karena lebih banyak catatan dan pengguna secara bersamaan meningkat.
sumber
Saya punya udf yang berisi string dan menempatkan output ke varchar (maks). Jika ini digunakan secara langsung, bukan casting kembali ke ukuran yang sesuai untuk kolom yang disesuaikan, kinerjanya sangat buruk. Saya akhirnya menempatkan udf ke panjang yang sewenang-wenang dengan catatan besar alih-alih mengandalkan semua penelepon udf untuk melemparkan kembali string ke ukuran yang lebih kecil.
sumber
dukungan sistem warisan. Jika Anda memiliki sistem yang menggunakan data dan diharapkan memiliki panjang tertentu, maka basis data adalah tempat yang baik untuk menegakkan panjang. Ini tidak ideal tetapi sistem warisan terkadang tidak ideal. = P
sumber
Jika semua data dalam satu baris (untuk semua kolom) tidak akan pernah cukup mengambil 8000 atau lebih sedikit karakter maka desain pada lapisan data harus memberlakukan ini.
Mesin database jauh lebih efisien menjaga semuanya dari penyimpanan gumpalan. Semakin kecil Anda dapat membatasi baris, semakin baik. Semakin banyak baris Anda dapat menjejalkan di halaman lebih baik. Basis data hanya berkinerja lebih baik ketika harus mengakses lebih sedikit halaman.
sumber
Tes saya menunjukkan bahwa ada perbedaan saat memilih.
sumber
Tautan yang menarik: Mengapa menggunakan VARCHAR saat Anda dapat menggunakan TEXT?
Ini tentang PostgreSQL dan MySQL, jadi analisis kinerjanya berbeda, tetapi logika untuk "explicitness" masih berlaku: Mengapa memaksakan diri untuk selalu khawatir tentang sesuatu yang relevan dengan persentase kecil dari waktu? Jika Anda menyimpan alamat email ke variabel, Anda akan menggunakan 'string' bukan 'string yang dibatasi hingga 80 karakter'.
sumber
Kerugian utama yang bisa saya lihat adalah katakanlah Anda memiliki ini:
Yang mana yang memberi Anda informasi paling banyak tentang data yang diperlukan untuk UI?
Ini
Atau ini?
sumber
Salah satu kelemahannya adalah bahwa Anda akan mendesain di sekitar variabel yang tidak dapat diprediksi, dan Anda mungkin akan mengabaikan alih-alih memanfaatkan struktur data SQL Server internal, yang secara progresif terdiri dari Baris, Halaman, dan Luas.
Yang membuat saya berpikir tentang penyelarasan struktur data dalam C, dan bahwa menyadari penyelarasan umumnya dianggap sebagai Good Thing (TM). Ide serupa, konteksnya berbeda.
Halaman MSDN untuk Halaman dan Luas
Halaman MSDN untuk Data Row-Overflow
sumber
pertama saya memikirkan hal ini, tetapi kemudian berpikir lagi. Ada implikasi kinerja, tetapi sama-sama berfungsi sebagai bentuk dokumentasi untuk memiliki gagasan ukuran bidang apa sebenarnya. Dan itu berlaku ketika database itu berada di ekosistem yang lebih besar. Menurut saya kuncinya adalah permisif tetapi hanya masuk akal.
ok, inilah perasaan saya hanya pada masalah logika bisnis dan lapisan data. Itu tergantung, jika DB Anda adalah sumber daya bersama antara sistem yang berbagi logika bisnis maka tentu saja itu tampaknya tempat alami untuk menegakkan logika tersebut, tetapi itu bukan cara TERBAIK untuk melakukannya, cara TERBAIK adalah menyediakan API, ini memungkinkan interaksi yang akan diuji dan membuat logika bisnis tetap berada di tempatnya, ia membuat sistem dipisahkan, menjaga tingkatan Anda dalam sistem dipisahkan. Namun, jika database Anda seharusnya hanya melayani satu aplikasi, maka mari kita berpikir, apa yang benar sekarang? desain untuk saat ini. Jika dan ketika akses tersebut diperlukan, berikan API ke data itu.
jelas, ini hanya yang ideal, jika Anda bekerja dengan sistem yang ada, kemungkinannya adalah bahwa Anda perlu melakukannya secara berbeda setidaknya dalam jangka pendek.
sumber
Ini akan menyebabkan masalah kinerja, meskipun mungkin tidak pernah menyebabkan masalah aktual jika database Anda kecil. Setiap catatan akan memakan lebih banyak ruang di hard drive dan database akan perlu membaca lebih banyak sektor disk jika Anda mencari melalui banyak catatan sekaligus. Misalnya, catatan kecil bisa muat 50 untuk sektor dan catatan besar bisa muat 5. Anda harus membaca 10 kali lebih banyak data dari disk menggunakan catatan besar.
sumber
nvarchar(max)
kolom tidak membutuhkan ruang disk lebih banyak daripada jika berada dalamnvarchar(100)
kolom.Ini akan membuat desain layar lebih sulit karena Anda tidak lagi dapat memprediksi seberapa lebar kontrol Anda seharusnya.
sumber