Czy pusta wartość kolumny zajmuje to samo miejsce do przechowywania co wypełniona wartość kolumny?


16

Mam tabelę z 2 kolumnami. Typ obu kolumn jest ustawiony navarchar(38) . Jeśli utworzę wiersz z pustą wartością dla jednej z kolumn, czy zajmie to samo miejsce do przechowywania, jakby wartość nie była pusta?

Innymi słowy, czy MySQL zarezerwuje przestrzeń dyskową dla kolumny (w zależności od jej typu) podczas tworzenia wiersza?

Odpowiedzi:


11

Z fizycznej struktury wiersza Innodb, punktor 7 pod REDUNDANT ROW_FORMAT

Wartość SQL NULL powoduje rezerwację jednego lub dwóch bajtów w katalogu rekordów. Poza tym wartość SQL NULL rezerwuje zero bajtów w części danych rekordu, jeśli jest przechowywana w kolumnie o zmiennej długości . W kolumnie o stałej długości rezerwuje stałą długość kolumny w części danych rekordu. Zarezerwowanie stałej przestrzeni dla wartości NULL umożliwia aktualizację kolumny z NULL na wartość inną niż NULL, która może zostać wykonana w miejscu bez powodowania fragmentacji strony indeksu.

Z fizycznej struktury wiersza Innodb, punktor # 2 pod COMPACT ROW_FORMAT

Część nagłówka rekordu o zmiennej długości zawiera wektor bitowy do wskazania NULL kolumn. Jeśli liczba kolumn w indeksie, która może wynosić NULL, wynosi N, wektor bitowy zajmuje bajty SUFITOWE (N / 8) . (Na przykład, jeśli jest gdzieś od 9 do 15 kolumn, które mogą mieć wartość NULL, wektor bitowy używa dwóch bajtów.) Kolumny, które są NULL, nie zajmują miejsca innego niż bit w tym wektorze . Część nagłówka o zmiennej długości zawiera również długości kolumn o zmiennej długości. Każda długość zajmuje jeden lub dwa bajty, w zależności od maksymalnej długości kolumny. Jeśli wszystkie kolumny w indeksie NIE mają wartości NULL i mają stałą długość, nagłówek rekordu nie ma części o zmiennej długości.

W oparciu o te punkty punktowe, oto, co NULLprzyjmuje wartość dla magazynu kolumny

  • zmienna długość: wartość NULL nie zajmuje miejsca w pamięci w samym wierszu
  • stała długość: Zajmuje zarezerwowane miejsce

Teraz musisz zdecydować się na użycie CHAR i VARCHAR ze względu na to, co przyniósł pierwszy punkt

Zarezerwowanie stałej przestrzeni dla wartości NULL umożliwia aktualizację kolumny z NULL na wartość inną niż NULL, aby można ją wykonać bez powodowania fragmentacji strony indeksu

Zapobiegnie to wprowadzaniu fragmentacji wiersza idącego w dół drogi po zapisaniu danych innych niż NULL. Jest to coś, co omówiłem wcześniej w odniesieniu do MyISAM: Zobacz mój stary post Jaki jest wpływ na wydajność używania CHAR vs VARCHAR na polu o stałym rozmiarze? .


Cześć Rolando, był inny element, o którym zapomniałem wspomnieć, różnica w alokacji pamięci między deklaracją typu varchar (5) i varchar (100). A tak naprawdę kara związana z nadmierną alokacją.
Craig Efrein

@CraigEfrein Zdecydowanie powinieneś dodać przydział pamięci do swojej odpowiedzi. (BTW, już głosowałem za odpowiedzią)
RolandoMySQLDBA,

1
Kara za nadmierne przydzielanie występuje, gdy masz kompleks, SELECTktóry musi utworzyć tabelę tymczasową. Jeśli to możliwe, użyje MEMORY, i przekonwertować VARCHARdo CHARdo tabeli tmp. Teraz VARCHAR(100)zajmuje ustalone 100 (lub 300) bajtów, co prawdopodobnie spowalnia zapytanie.
Rick James,

@RolandoMySQLDBA, czy zachowanie wyjaśnione w odpowiedzi dotyczy formatów wierszy DYNAMIC i COMPACT w Mysql 5.7.
Dinesh Kumar,

@DineshKumar Te akapity są nadal w Dokumentach 5.7 / 8.0. Informacje na temat DYNAMIC można znaleźć na stronie dev.mysql.com/doc/refman/5.7/en/innodb-row-format-dynamic.html .
RolandoMySQLDBA

8

Bez względu na długość, którą określisz dla swojej kolumny varchar, przestrzeń dyskowa używana przez pustą kolumnę będzie taka sama.

Typy CHAR i VARCHAR

wprowadź opis zdjęcia tutaj

Dotyczy to tylko miejsca używanego przez kolumnę varchar i nie uwzględnia całkowitej przestrzeni dyskowej używanej przez wiersz, jego indeksów, kluczy podstawowych i innych kolumn.

Jak wspomina ypercube w swoim komentarzu, istnieją dodatkowe uwagi dotyczące przechowywania wierszy jako całości, gdy obecna jest co najmniej jedna kolumna z dopuszczalnymi wartościami.

Fizyczna struktura rzędów Innodb

Część nagłówka rekordu o zmiennej długości zawiera wektor bitowy do wskazania NULL kolumn. Jeśli jest gdzieś od 9 do 15 kolumn, które mogą mieć wartość NULL, wektor bitowy używa dwóch bajtów.)

...

Część nagłówka o zmiennej długości zawiera również długości kolumn o zmiennej długości. Każda długość zajmuje jeden lub dwa bajty, w zależności od maksymalnej długości kolumny. Jeśli wszystkie kolumny w indeksie NIE mają wartości NULL i mają stałą długość, nagłówek rekordu nie ma części o zmiennej długości

I tak, używane miejsce do przechowywania zmienia się w zależności od wybranego typu, czy jest stały, czy zmienny, sortowanie i inne czynniki, takie jak silnik.

MySQL zawiera zalecenia dotyczące optymalizacji przechowywania danych: Optymalizacja rozmiaru danych

Aktualizacja

Dodatkowa uwaga związana z varchar i pamięcią. W MySQL ważne jest, aby maksymalnie ograniczyć rozmiar kolumny o zmiennej długości. Mimo że kolumna jest zmienna, a używane miejsce do przechowywania jest zmienne, MySQL przydzieli pamięć w stałych porcjach do przechowywania wartości. Na przykład varchar (200) zużyje więcej pamięci niż varchar (5). To nie jest problem z przestrzenią dyskową, ale wciąż coś do rozważenia przy definiowaniu kolumn.


Liczby powyżej zakładają CHARACTER SETlatin1 lub ascii. W przypadku utf8 wymagana pamięć CHAR(4)to 12.
Rick James
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.