varchar'ın (500) varchar'a (8000) göre bir avantajı var mı?


91

Bunu MSDN forumlarında ve burada okudum ve hala net değilim. Bunun doğru olduğunu düşünüyorum: Varchar (max) bir metin veri türü olarak saklanacak, bu yüzden dezavantajları var. Alanınızın güvenilir bir şekilde 8000 karakterin altında olacağını varsayalım. Veritabanı tablomdaki bir BusinessName alanı gibi. Gerçekte, bir işletme adı muhtemelen her zaman (şapkamdan bir sayı çıkararak) 500 karakterin altında olacaktır. Karşılaştığım birçok varchar alanı 8k karakter sayımının oldukça altında kalıyor gibi görünüyor.

Yani bu alanı varchar (8000) yerine varchar (500) yapmalı mıyım? SQL'den anladığım kadarıyla bu ikisi arasında hiçbir fark yok. Bu yüzden hayatı kolaylaştırmak için tüm varchar alanlarımı varchar (8000) olarak tanımlamak istiyorum. Bunun herhangi bir sakıncası var mı?

İlgili: Varchar sütunlarının boyutu (Bunun sorumu yanıtladığını düşünmedim).


6
Kartvizite 500 karakter uzunluğunda bir işletme adı sığdırmaya çalıştığınızı hayal edin ... :)
OMG Ponies

2
@OMG Ponies: Kullanıcı adınızı her gördüğümde kıkırdıyorum. Şimdi ne diyordun? (Şaka yapıyorum)
jcollum

4
@jcollum: SpaceMan Spiff her zaman oyumu alacak. Bu doğru değil - herhangi bir Calvin & Hobbes yapacak, ama özellikle kar şekillendiren olanlar. Veya bir F-14 uçuran tyranosaurus. Ama ben daldım ...
OMG Ponies

Yanıtlar:


21

İşleme açısından, varchar (8000) ve varchar (500) kullanmak bir fark yaratmayacaktır. Bir alanın tutması gereken maksimum uzunluğu tanımlamak ve varchar'ınızı bu uzunlukta yapmak daha çok "iyi uygulama" türünden bir şeydir. Veri doğrulamasına yardımcı olmak için kullanılabilecek bir şey. Örneğin, bir eyalet kısaltmasının 2 karakter veya 5 veya 9 karakter olarak bir posta / posta kodu olması. Bu, verilerinizin alan uzunluğunun kritik olduğu diğer sistemlerle veya kullanıcı arayüzleriyle etkileşime girdiğinde daha önemli bir ayrımdı (örneğin, ana bilgisayar düz dosya veri kümesi), ancak günümüzde bunun her şeyden daha alışkanlık olduğunu düşünüyorum.


3
Doğal olarak maksimum uzunluğa sahip şeyler için mantıklı. Ama maksimum uzunluk belli olmadığında ne yaparsınız? Örneğin bir işletme adı.
jcollum

2
Böyle bir şey için, boyutun potansiyel olarak ne olabileceğini tahmin etmenin herhangi bir yolunu öngörmezsem, o zaman genellikle veri türüne bağlı olarak bir varchar (8000) veya varchar (max) ile
giderim

4
Görünüşe göre bu, 2017'de bile performansta bir fark yaratıyor
a_horse_with_no_name

2
Daha yeni cevaplar , maliyetlerin olduğunu gösteriyor : Optimizasyon mantığını etkiliyor Martin Smith'in cevabını etkiliyor ve ayrıca gbn ve Oliver tarafından bahsedilen 8K toplam satır boyutu sorunlarını dikkate alıyor .
ToolmakerSteve

125

Bunun fark yaratabileceği bir örnek, ardıl tetikleyicilere sahip tablolara satır sürüm bilgisi eklemekten kaçınan bir performans optimizasyonunu engelleyebilmesidir.

Bu, burada SQL Kiwi tarafından kapsanmaktadır

Depolanan verilerin gerçek boyutu önemsizdir - önemli olan potansiyel boyuttur.

Benzer şekilde, 2016'dan beri bellek için optimize edilmiş tablolar kullanılıyorsa, giriş sınırını potansiyel olarak aşabilecek, ancak bir ceza ile LOB sütunlarını veya sütun genişliği kombinasyonlarını kullanmak mümkün olmuştur.

(Maks.) Sütunlar her zaman satır dışında saklanır. Diğer sütunlar için, tablo tanımındaki veri satırı boyutu 8.060 baytı aşabilirse, SQL Server en büyük değişken uzunluklu sütunu / sütunları satır dışına iter. Yine, orada sakladığınız verilerin miktarına bağlı değildir.

Bunun bellek tüketimi ve performans üzerinde büyük bir olumsuz etkisi olabilir

Aşırı bildirimin sütun genişliklerinin büyük bir fark yaratabileceği bir başka durum, tablonun SSIS kullanılarak işlenip işlenmeyeceğidir. Değişken uzunluklu (BLOB olmayan) sütunlar için ayrılan bellek, bir yürütme ağacındaki her satır için sabittir ve bellek arabelleklerinin verimsiz kullanımına yol açabilecek şekilde sütunların beyan edilen maksimum uzunluğuna göre belirlenir (örnek) . SSIS paket geliştiricisi kaynaktan daha küçük bir sütun boyutu bildirebilirken, bu analiz en iyi şekilde önceden yapılır ve orada uygulanır.

SQL Server motorunun kendisine geri döndüğümüzde benzer bir durum, SORTişlemler için ayırmak üzere bellek tahsisatını hesaplarken SQL Server'ın varchar(x)sütunların ortalama olarak x/2bayt tüketeceğini varsaymasıdır .

Senin en Eğer varcharsütunlar bu yol açabilir bundan daha dolgun sortdöken operasyonlar tempdb.

Sizin durumunuzda, varcharsütunlarınız 8000bayt olarak bildirilmişse, ancak gerçekte bundan çok daha az içeriğe sahipse, sorgunuza gerektirmeyen bellek tahsis edilecektir, bu açıkça verimsizdir ve bellek izinleri için beklemelere yol açabilir.

Bu, buradan indirilebilen SQL Workshops Webcast 1 Bölüm 2'de ele alınmıştır veya aşağıya bakınız.

use tempdb;

CREATE TABLE T(
id INT IDENTITY(1,1) PRIMARY KEY,
number int,
name8000 VARCHAR(8000),
name500 VARCHAR(500))

INSERT INTO  T 
(number,name8000,name500)
SELECT number, name, name /*<--Same contents in both cols*/
FROM master..spt_values

SELECT id,name500
FROM T
ORDER BY number

Ekran görüntüsü

SELECT id,name8000
FROM T
ORDER BY number

Ekran görüntüsü


1
bu nedenle, neredeyse tüm değerlerim 3 veya 4 karakter ise, hiçbir zaman 4 karakteri geçemezse ve "tempdb'ye dökülen işlemleri sıralamaktan" kaçınmak istiyorsam, sütunumu VARCHAR (8) olarak bildireceğim ve bu sütunu uygulamak için bir KONTROL kısıtlaması kullanacağım genişlik 4 karakteri geçemez. Ne düşünüyorsun?
AK

12
@AlexKuznetsov - Bu durumda, onları char(4)değişken sütun başına 2 bayt ek yük varmış gibi bildirirdim .
Martin Smith

10

En iyi uygulamaların dışında (BBlake'in cevabı)

  • DDL ile maksimum satır boyutu (8060) bayt ve dizin genişliği (900 bayt) hakkında uyarılar alırsınız
  • Bu sınırları aşarsanız DML ölür
  • ANSI PADDING ON varsayılandır, böylece bir beyaz boşluk yükünün tamamını depolayabilirsiniz.

39
Sadece ANSI DOLDURMA yaklaşık netleştirmek için: kullanıldığında nvarcharve varchartipleri, takip eden boşluklar ekin üzerine korunur, bu tek yolu - değerleri olarak kolon büyüklüğüne, boşluklarla yastıklı değil charve nchar.
Ben M

9

Büyük sütunların biraz daha az belirgin olan ve sizi biraz sonra yakalayabilecek bazı dezavantajları vardır:

  • Bir INDEX'te kullandığınız tüm sütunlar - 900 baytı geçmemelidir
  • ORDER BY yan tümcesindeki tüm sütunlar 8060 baytı geçemez. Bu sadece bazı sütunlar için geçerli olduğu için bunu kavramak biraz zor. Ayrıntılar için SQL 2008 R2 Satır boyutu sınırı aşıldı konusuna bakın )
  • Toplam satır boyutu 8060 baytı aşarsa, o satır için bir " sayfa dökülmesi " elde edersiniz . Bu, performansı etkileyebilir (Bir sayfa, SQLServer'da bir ayırma birimidir ve 8000 bayt + biraz ek yük olarak sabitlenmiştir. Bunu aşmak ciddi olmayacaktır, ancak farkedilebilir ve eğer kolayca yapabiliyorsanız, bundan kaçınmaya çalışmalısınız)
  • Diğer birçok dahili veri yapısı, arabellek ve en önemlisi, kendi değişkenleriniz ve tablo değişkenlerinizin tümü bu boyutları yansıtmalıdır. Aşırı boyutlarda, aşırı bellek ayırma performansı etkileyebilir

Genel bir kural olarak, sütun genişliğiyle ölçülü olmaya çalışın. Bir sorun haline gelirse, ihtiyaçlara uyacak şekilde kolayca genişletebilirsiniz. Daha sonra bellek sorunlarını fark ederseniz, verileri kaybetmeden geniş bir sütunu küçültmek imkansız hale gelebilir ve nereden başlayacağınızı bilemezsiniz.

İşletme adlarıyla ilgili örneğinizde, onları nerede sergileyeceğinizi düşünün. 500 karakter için gerçekten yer var mı? Değilse, bu şekilde saklamanın pek bir anlamı yoktur. http://en.wikipedia.org/wiki/List_of_companies_of_the_United_States bazı şirket adlarını listeler ve maksimum değer yaklaşık 50 karakterdir. Bu yüzden maksimum sütun için 100 kullanırım. Belki daha çok 80 gibi.


2

İdeal olarak, bundan daha küçük, makul boyutta bir uzunluğa (500 makul boyutta değildir) gitmek ve istemci doğrulamasının, veriler çok büyük olduğunda yakaladığından ve yararlı bir hata gönderdiğinden emin olmak istersiniz.

Varchar aslında kullanılmayan alan için veritabanında yer ayırmayacak olsa da, SQL Server sürümlerinin veritabanı satırlarının bazı bayttan daha geniş olduğu (tam sayımı hatırlamıyorum) ve aslında dışarı atıldığını hatırlıyorum. ne veri uymuyorsa. Bu baytların belirli bir kısmı SQL Server'ın içindeki şeyler için ayrılmıştı.


doğru, bu eskiden çok daha büyük bir endişe kaynağıydı. Ancak günümüzde, alan gerçekten ucuz, bu yüzden en azından benim bakış açıma göre bunun dikkate alınması gereken büyük bir endişe olduğunu düşünmüyorum.
BBlake

1
@jcollum: Örneğinizde, 500 bir işletme adı için makul boyutta görünmüyor.
Otis

1
@BBlake: Depolama maliyetinden bağımsız olarak, SQL Server'da hala satır boyutu kısıtlamaları varsa, ne kadar depolama alanınız olduğu önemli değildir. Her şeyi textblob'larda saklayabilirsiniz, ancak bir varchar üzerinde yapabileceğiniz bir blob üzerinde yapamayacağınız bazı SQL işlemleri vardır.
Otis

2
@Otis: Demek istediğim şu: bir işletme adının boyutunda gerçek bir kısıtlama yok. Bir yerde yasa yoksa. Bu durumda, bu alanı varchar (8000) yapıp bir gün olarak adlandırırım. Benim düşüncem şöyle: Gerçek kısıtlama mı? varchar (x). Gerçek bir kısıtlama yok mu? varchar (8000).
jcollum

24
Ben 30 düşünce ya da ben El Pueblo de Nuestra Senora la Reina de los Ángeles del Río de Porciúncula görene kadar karakter yüzden, şehir adları için iyi oldu
StuartLC
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.