Czy puste kolumny zajmują miejsce w tabeli?

20

Mam stolik, który zawiera bardzo podstawowe informacje. Tylko tytuł i kilka pól daty. Jest jedno pole zwane komentarzami, które jest varchar (4000). Zazwyczaj pozostawiamy je puste, ale czasami wprowadzimy tutaj dużą ilość danych. Czy to naprawdę zły projekt? Czy jest to tylko trochę nieefektywne?

Zakładam, że utworzenie oddzielnej tabeli dla tej kolumny byłoby lepsze.

Uwaga: jest to serwer SQL 2008

wprowadź opis zdjęcia tutaj

aron
źródło
Dziękujemy za opinię wszystkim! Postanowiłem uprościć sprawę i zachować kolumnę w tabeli, a nie umieszczać jej w innej tabeli. Jednak użyłem funkcji SPARSE w SQL 2008, więc pole nie zajmuje miejsca.
2
Ciekawe, co to jest „przez większość czasu”? Ile wierszy łącznie i jaki procent ma tutaj wartość? Zastanawiam się tylko, czy planujesz dokonać porównań przestrzeni / wydajności, używając, SPARSEa nie używając SPARSE...
Aaron Bertrand

Odpowiedzi:

9

Aby uzyskać bardziej przewidywalną wydajność (i aby uniknąć dużej zmienności wierszy na stronę), skłaniałbym się do przechowywania tych danych w powiązanej tabeli - szczególnie jeśli jest on zapełniany tylko przez niewielki procent czasu, a zwłaszcza jeśli jest on pobierany tylko w niektóre zapytania. Wiersze, w których ta wartość jest NULL, przyczyniają się do narzutu miejsca, ale jest to minimalne. Ważniejsze będzie to, w jaki sposób jedna strona może zmieścić tylko dwa wiersze, a następna strona może zmieścić 500 wierszy - może to naprawdę wpłynąć na statystyki i lepiej jest podzielić to, aby było przechowywane osobno i nie wpłynęło na wszystkie operacje na rdzeń stołu.

Aaron Bertrand
źródło
12

Nieużywany zajmuje minimalną przestrzeń

  • jeden bit w mapie bitowej NULL
  • dwa bajty dla długości (która będzie równa zero, gdy NULL)

Koszty ogólne są minimalne, a optymalizacja będzie przedwczesna.

Dopóki nie dowiesz się, że masz problem, po prostu trzymaj go w jednym stole. Łamiesz KISS, wprowadzając sprzężenia zewnętrzne i dodajesz narzut w zapytaniach o dane.

Zobacz /programming/3793022/how-to-come-to-limits-of-8060-bytes-per-row-and-8000-per-varchar-nvarchar-valu/3793265#3793265 dłużej

gbn
źródło
10

Myślę, że osobna tabela byłaby lepsza dla poprawy gęstości strony i zmniejszenia fragmentacji, szczególnie jeśli nie zawsze wypełniasz to pole.

  • Strona danych zawiera około 8000 bajtów
  • Masz kilka wierszy ze powiedzmy 100 bajtami i niektóre wiersze z ponad 4000 bajtów
  • Te długie wiersze będą same na stronie, a reszta strony to „zmarnowane” miejsce, które zajmuje twoja baza danych, ale prawdopodobnie nigdy nie pomieści danych
  • Jeśli dodasz dane do tego długiego pola dla rekordu na przeważnie pełnej stronie, najprawdopodobniej spowoduje to przekroczenie strony i spowoduje wyświetlenie wskaźnika do strony z resztą rekordu

Wszystkie te puste strony i wskaźniki prowadzą do niskiej wydajności. Znormalizuj to pole, jeśli możesz.

JNK
źródło
4

To pytanie wygląda bardzo podobnie: czy dodatkowe puste kolumny znacząco wpływają na rozmiar tabeli sql?

Wygląda na to, że odpowiedź brzmi tak, zajmuje miejsce, ale istnieje algorytm kompresji dla kolumn z dużą ilością wartości null.

Jeśli chodzi o projekt, myślę, że powiązanie z nim zewnętrznego stołu byłoby czystszym projektem. Posiadanie kolumny z częstymi wartościami null utrudnia użytkownikom bazy danych, ponieważ mogą przypadkowo użyć wartości null, jeśli nie są ostrożni. Dlatego kod korzystający z bazy danych musiałby zawierać sprawdzanie błędów i stamtąd robi się brzydki.

Społeczność
źródło
2
Mówiąc wprost, algorytm kompresji stosuje się tylko do tych kolumn, które są wyraźnie zdefiniowane jako SPARSE, a nie tylko „kolumny z dużą ilością zerowych wartości”.
Aaron Bertrand
2

Nic ci nie będzie - to już kolumna varchar, więc używa miejsca tylko wtedy, gdy zawiera dane. Jeśli masz wiele zerowalnych kolumn o stałym rozmiarze, takich jak int, możesz mieć problemy z wykorzystaniem miejsca.

Jeśli chodzi o umieszczenie go w innym stole, nie zawracałbym sobie głowy. Możesz także spojrzeć na użycie varchar (max) i opcji in / out of row. Znowu, prawdopodobnie przedwcześnie.

Cade Roux
źródło
1
Przedwczesna optymalizacja może często być prawdziwym problemem, ale zależy to od kosztu późniejszego refaktoryzacji. Jeśli wiesz dzisiaj, że tylko 1% twoich wierszy będzie zawierało dane w tej kolumnie, i oczekujesz, że tabela będzie rosła z czasem, jaka jest wartość utrzymywania tych danych w bieżącej tabeli tylko po to, by skalować? Jestem za unikaniem przedwczesnej optymalizacji, ale jest moment, kiedy ważę długoterminowy efekt takiego działania.
Aaron Bertrand
@Aaron Bertrand wyraził zgodę. Ludzie zadają tutaj pytania dotyczące wydajności i łatwo założyć, że mogą mieć aplikację zawierającą miliony wierszy i muszą używać każdej broni w zestawie narzędzi i mieć to wszystko na uwadze. Z drugiej strony, czasami użytkownik wydaje się być na początku krzywej uczenia się i trudno jest poprosić go o poświęcenie czasu na coś, co prawdopodobnie powinno mieć niższe priorytety. Ponadto, dzięki varchar (max), możesz skutecznie przesunąć przełącznik, aby rozpocząć przechowywanie poza rzędem. Myślę, że prawdziwa odpowiedź brzmi: „Tak naprawdę nie dostarczyłeś nam wystarczających informacji, aby udzielić ostatecznej odpowiedzi”.
Cade Roux,