Czy powinienem używać varchar(255)
lub varchar(256)
przy projektowaniu stołów? Słyszałem, że jeden bajt jest używany dla długości kolumny lub do przechowywania metadanych.
Czy w tym momencie ma to już znaczenie?
Widziałem kilka postów w Internecie, jednak dotyczą one Oracle i MySQL.
Mamy Microsoft SQL Server 2016 Enterprise Edition, w jaki sposób ma on zastosowanie do tego środowiska?
Teraz powiedzmy na przykład: co jeśli kazałem moim klientom zachować na przykład opis tekstowy do 255 znaków zamiast 256, czy jest jakaś różnica? Co przeczytałem „Przy maksymalnej długości 255 znaków DBMS może wybrać pojedynczy bajt do wskazania długości danych w polu. Gdyby limit wynosił 256 lub więcej, potrzebne byłyby dwa bajty”. Czy to prawda?
Odpowiedzi:
Rozmiar każdej kolumny odpowiednio. NIE używaj „standardowego” rozmiaru dla każdej kolumny. Jeśli potrzebujesz tylko 30 znaków, po co tworzyć kolumnę, która może obsłużyć 255? Tak się cieszę, że nie zalecasz używania
varchar(max)
swoich kolumn ciągów.Jest to szczególnie rozsądna rada, jeśli kiedykolwiek będziesz potrzebować zaindeksować kolumnę lub jeśli używasz kolumny jako klucza podstawowego i ma ona odniesienia do klucza obcego. SQL Server używa wielkości każdej kolumny w swoim optymalizatorze zapytań, aby zrozumieć szacunkowe wymagania pamięci dla przetwarzania zapytań. Posiadanie zbyt dużych kolumn może mieć negatywny wpływ na wydajność.
Indeksy w kolumnach, które są zbyt duże, mogą powodować generowanie błędów:
Próba utworzenia powyższego indeksu powoduje wyświetlenie tego ostrzeżenia:
900 bajtów to maksymalny rozmiar klucza dla indeksów klastrowych (i indeksów nieklastrowanych w SQL Server 2012 i starszych). 1700 bajtów to maksymalny rozmiar klucza dla indeksów nieklastrowanych w nowszych wersjach SQL Server. Jeśli projektujesz kolumny o ogólnej szerokości, takie jak (255), możesz spotkać się z tym ostrzeżeniem znacznie częściej niż oczekiwano.
Jeśli interesują Cię wewnętrzne elementy pamięci, możesz skorzystać z następującego drobnego testu, aby lepiej zrozumieć, w jaki sposób SQL Server przechowuje nieskompresowane dane z magazynu wierszy.
Najpierw utworzymy tabelę, w której możemy przechowywać kolumny o różnych rozmiarach:
Teraz wstawimy pojedynczy wiersz:
W tym zapytaniu wykorzystano nieudokumentowane i nieobsługiwane funkcje
sys.fn_RowDumpCracker
orazsys.fn_PhyslocCracker
pokazano kilka interesujących szczegółów dotyczących tabeli:Dane wyjściowe będą wyglądać podobnie do tego:
Jak widać,
InRowLength
dla każdej wartości jest wyświetlana wraz z fizyczną lokalizacją każdego wiersza - „id_pliku”, „id_strony” i „id_boksu”.Jeśli weźmiemy wartości
file_id
ipage_id
z powyższych wyników zapytania i uruchomimyDBCC PAGE
je, możemy zobaczyć rzeczywistą fizyczną zawartość strony:Wyniki z mojej maszyny to:
źródło
Inni zauważyli już, że liczba bajtów wymagana do przechowywania długości jest stała. Chciałem skoncentrować się na tej części w twoim pytaniu:
Twoje pytanie zostało otagowane wersją Enterprise, co ogólnie oznacza, że będziesz mieć sporo danych. Często różnice w jednym bajcie na wiersz naprawdę nie mają większego znaczenia w praktyce. Na przykład poniższa tabela z w pełni wypełnioną
VARCHAR(255)
kolumną zajmuje 143176 KB miejsca na dysku:Wyniki:
Utwórzmy drugą tabelę z w pełni wypełnioną
VARCHAR(256)
kolumną. To zajmie przynajmniej jeden bajt na wiersz, prawda?Wyniki:
Tak się składa, że obie tabele zajmują tyle samo miejsca. Ta sama liczba wierszy mieści się na każdej stronie o wielkości 8 tys. To wspaniałe, że chcesz spędzić czas na optymalizacji aplikacji, ale podejrzewam, że lepiej skupić się na różnych obszarach.
źródło
Deklarowany rozmiar varchara nie ma wpływu na wydajność. Dane mogą być faktycznie przechowywane jako magazyn wierszy z kompresją strony lub kompresją wiersza. Jako klastrowany magazyn kolumn lub jako tabela zoptymalizowana pod kątem pamięci. Każdy z nich będzie miał różne kompromisy wydajnościowe, ale nigdy nie ma znaczenia, czy zadeklarujesz varchar (255) czy varchar (256).
źródło