W SQL Server dlaczego maleintka jest przechowywana z 9B w wierszu. Z jakiegoś powodu wydaje się, że na końcu maski bitmapowej NULL jest dodatkowy jeden bajt.
USE tempdb; UDAĆ SIĘ UTWÓRZ TABELĘ tbl ( i TINYINT NOT NULL ); UDAĆ SIĘ INSERT INTO tbl (i) WARTOŚCI (1); UDAĆ SIĘ DBCC IND („tempdb”, „tbl”, - 1); UDAĆ SIĘ DBCC TRACEON (3604); - Zrzut strony przejdzie do konsoli UDAĆ SIĘ STRONA DBCC („tempdb”, 1,168,3); UDAĆ SIĘ
Wyniki (odwróciłem bajty, ponieważ strona DBCC pokazuje najpierw najmniej znaczący bajt):
Record Size = 9B
10000500 01010000 00
TagA = 0x10 = 1B
TagB = 0x00 = 1B
Null Bitmap Offset = 0x0005 = 2B
Our integer column = 0x01 = 1B
Column Count = 0x0001 = 2B
NULL Bitmap = 0x0000 = 2B (what!?)
sql-server-2008
ooutwire
źródło
źródło
Odpowiedzi:
Jeśli obliczysz rekord za pomocą prostego dodania rozmiaru, rzeczywiście otrzymasz 8: 4 + 1 + 2 + 1 (nagłówek + ustalony rozmiar + zerowa liczba bitmap + sama pusta bitmapa). Ale rekord stosu nie może być mniejszy niż rozmiar kodu przekierowującego , który wynosi 9 bajtów, ponieważ rekord musi gwarantować , że można go zastąpić kodem przekierowującym. Stąd rekord będzie faktycznie o 9 bajtów. A
smallint
będzie mieć 9 bajtów zarówno za pomocą obliczeń, jak i rozmiaru minimalnego. Coś większego jest już większe niż kod pośredniczący przesyłania, więc Twój rozmiar obliczeniowy jest zgodny z rozmiarem rekordu.źródło
CREATE TABLE tbl (i TINYINT NOT NULL PRIMARY KEY)
więc czy jest to tylko ogólna reguła dla wszystkich wierszy, niezależnie od tego, czy są one częścią stosu?alter table ... drop constraint
), a operacja nie jest pełną przebudową (górne strony b-drzewa zostają wyrzucone, strony liści pozostaną rozłączone, a wynikiem jest sterta), więc logika rezerwacji nadal obowiązuje .Miło mieć ucho autora. :-) Kalen podejrzewa, że jest to tylko egzekwowanie pewnej minimalnej długości wiersza, gdzie wszystko <9 jest dopełniane do 9. Oczywiście jest tylko kilka przypadków, w których jest to możliwe. Ten fantomowy bajt znajdziesz dla TINYINT i BIT, a także VARCHAR (1) / CHAR (1). Nie wzrośnie powyżej 9, jeśli przejdziesz do SMALLINT lub CHAR (2), ale wzrośnie, jeśli przejdziesz do, powiedzmy, CHAR (3).
Zasadniczo możesz więc wskazać wydajność, którą możesz zyskać, mądrze wybierając typy danych, ale zwróć uwagę, że istnieją pewne przypadki skrajne, w których reguły nie obowiązują z powodu innych czynników w warstwie pamięci.
EDYTUJ Mam nadzieję, że będę miał dla ciebie bardziej konkretne informacje. Chciałem tylko poinformować, że tak właśnie myśli obecnie autor książki o Internals. Nie jest w 100% pewna.
źródło