Dengan SQL Server 2019 Microsoft memperkenalkan dukungan UTF-8 untuk CHAR
dan VARCHAR
tipe data dan mengatakan:
Fitur ini dapat memberikan penghematan penyimpanan yang signifikan, tergantung pada karakter yang digunakan. Misalnya, mengubah tipe data kolom yang ada dengan string ASCII dari NCHAR (10) ke CHAR (10) menggunakan collation yang diaktifkan UTF-8, diterjemahkan menjadi pengurangan hampir 50% dalam persyaratan penyimpanan. Pengurangan ini karena NCHAR (10) membutuhkan 22 byte untuk penyimpanan, sedangkan CHAR (10) membutuhkan 12 byte untuk string Unicode yang sama.
UTF-8 tampaknya mendukung setiap skrip, jadi pada dasarnya kita dapat mulai menyimpan data varchar
dan char
kolom Unicode . Dan seperti yang dikatakan dalam dokumentasi, ini dapat mengurangi ukuran tabel dan indeks, dan dari sana kita bisa mendapatkan kinerja yang lebih baik, karena jumlah data yang lebih sedikit dibaca.
Saya bertanya-tanya apakah ini berarti kita dapat berhenti menggunakan nvarchar
dan nchar
kolom yang mengimplementasikan UTF-16?
Adakah yang bisa menunjukkan skenario dan alasan, untuk tidak menggunakan tipe data char dengan UTF
encoding dan terus menggunakan n-chars?
CHAR
jenis UTF-8 daripada jenis Unicode (dengan atau tanpa kompresi, karena pada akhirnya data perlu dikompresi untuk diproses). Pertimbangkan juga bahwa tipe string asli Windows adalah Unicode, jadi string UTF-8 sering perlu diterjemahkan. Pengorbanan yang terlibat berarti tidak mungkin bahwaN
jenis akan dihentikan dalam waktu dekat.CHAR
mungkin adalah SQL Server di Linux, jika mesin mendapatkan dukungan asli untuk memproses string secara langsung sebagai UTF-8 - di sini UTF-8 adalah rangkaian karakter "asli" (kurang lebih) dan menjaga string sebagai UTF-16 adalah alternatif yang kurang efisien. Juga tidak ada salahnya untuk menggunakannya pada Windows di tempat-tempat yang sudah Anda gunakanCHAR
, tentu saja, karena pengumpulan yang membatasi karakter yang dapat disimpan tidak pernah menarik.Jawaban:
Pengurangan ukuran hanya mungkin jika sebagian dari karakter dasarnya
[space]
,0 - 9
,A - Z
,a - z
, dan beberapa tanda baca dasar. Di luar itu spesifik set karakter (dalam hal penggunaan praktis, nilai-nilai ASCII standar 32-126), Anda akan di terbaik sama dengan ukuranNVARCHAR
/ UTF-16, atau dalam banyak kasus yang lebih besar.Hati-hati. UTF-8 bukanlah saklar ajaib "perbaiki semuanya". Semua hal lain dianggap sama, ya, kurang membaca meningkatkan kinerja. Tetapi di sini "semua hal lain" tidak sama. Bahkan ketika menyimpan hanya karakter ASCII standar (artinya: semua karakter adalah 1 byte, karenanya membutuhkan setengah ruang dibandingkan dengan menyimpan di
NVARCHAR
), ada sedikit penalti kinerja untuk menggunakan UTF-8. Saya percaya masalah ini karena UTF-8 menjadi pengkodean variabel-panjang, yang berarti bahwa setiap byte harus ditafsirkan ketika dibaca untuk mengetahui apakah itu karakter yang lengkap atau jika byte berikutnya adalah bagian dari itu. Ini berarti bahwa semua operasi string harus dimulai dari awal dan melanjutkan byte-by-byte. Di samping itu,NVARCHAR
/ UTF-16 selalu 2 byte (bahkan Karakter Tambahan terdiri dari dua Poin Kode 2-byte), sehingga semuanya dapat dibaca dalam potongan 2-byte.Dalam pengujian saya, bahkan dengan hanya karakter ASCII standar, menyimpan data sebagai UTF-8 tidak memberikan penghematan waktu yang telah berlalu, tetapi jelas lebih buruk untuk waktu CPU. Dan itu tanpa Kompresi Data, jadi setidaknya ada sedikit ruang disk yang digunakan. Tetapi, ketika menggunakan kompresi, ruang yang dibutuhkan untuk UTF-8 hanya 1% - 1,5% lebih kecil. Jadi secara efektif tidak ada penghematan ruang namun waktu CPU lebih tinggi untuk UTF-8.
Hal-hal menjadi lebih rumit ketika menggunakan
NVARCHAR(MAX)
karena Unicode Compression tidak bekerja dengan tipe data itu, bahkan jika nilainya cukup kecil untuk disimpan dalam baris. Tetapi, jika datanya cukup kecil, seharusnya masih mendapat manfaat dari Row atau Page Compression (dalam hal ini sebenarnya menjadi lebih cepat daripada UTF-8). Namun, data offline tidak dapat menggunakan kompresi apa pun. Namun, membuat tabel Clustered Columnstore Index tidak sangat mengurangi ukuranNVARCHAR(MAX)
(bahkan jika itu masih sedikit lebih besar dari UTF-8 saat menggunakan Clustered Columnstore Index).Pastinya. Sebenarnya, saya tidak benar-benar menemukan alasan kuat untuk menggunakannya dalam banyak kasus. Satu-satunya skenario yang benar-benar mendapat manfaat dari UTF-8 adalah:
VARCHAR
)Pengujian saya menunjukkan bahwa dalam hampir semua kasus, NVARCHAR lebih cepat, terutama ketika ada lebih banyak data. Bahkan, 21k baris dengan rata-rata 5k karakter per baris membutuhkan 165 MB untuk UTF-8 dan 236 MB untuk yang
NVARCHAR
tidak terkompresi. NamunNVARCHAR
2x lebih cepat dalam waktu berlalu, dan setidaknya 2x lebih cepat (kadang-kadang lebih) dalam waktu CPU. Namun, itu membutuhkan 71 MB lebih banyak pada disk.Di luar itu, saya masih tidak akan merekomendasikan menggunakan UTF-8, setidaknya pada CTP 2, karena berbagai bug yang saya temukan di fitur ini.
Untuk analisis terperinci fitur baru ini, termasuk penjelasan tentang perbedaan antara UTF-16 dan UTF-8, dan daftar bug tersebut, silakan lihat posting saya:
Dukungan UTF-8 Asli di SQL Server 2019: Juruselamat atau Nabi Palsu?
sumber
Dukungan UTF-8 memberi Anda satu set opsi baru. Penghematan ruang potensial (tanpa kompresi baris atau halaman ) adalah salah satu pertimbangan, tetapi pilihan jenis dan pengodean mungkin terutama harus dibuat berdasarkan persyaratan aktual untuk perbandingan, pengurutan, impor data, dan ekspor .
Anda mungkin perlu mengubah lebih dari yang Anda pikirkan, karena misalnya suatu
nchar(1)
tipe menyediakan dua byte penyimpanan. Itu cukup untuk menyimpan karakter apa pun di BMP (titik kode 000000 ke 00FFFF). Beberapa karakter dalam kisaran itu akan dikodekan dengan hanya 1 byte di UTF-8 sementara yang lain akan membutuhkan 2 atau bahkan 3 byte (lihat tabel perbandingan ini untuk lebih jelasnya). Oleh karena itu, memastikan cakupan set karakter yang sama di UTF-8 akan dibutuhkanchar(3)
.Sebagai contoh:
memberikan kesalahan yang umum:
Atau jika trace flag 460 aktif:
Memperluas kolom UTF8 ke
char(2)
atauvarchar(2)
mengatasi kesalahan untukNCHAR(911)
:Namun, jika itu mis.
NCHAR(8364)
, Anda perlu memperluas kolom lebih lanjut, kechar(3)
atauvarchar(3)
.Perhatikan juga bahwa UTF-8 collations semuanya menggunakan karakter tambahan, jadi tidak akan bekerja dengan replikasi.
Selain hal lain, dukungan UTF-8 hanya dalam pratinjau saat ini, jadi tidak tersedia untuk penggunaan produksi.
sumber