Czy logiczne uporządkowanie kolumn w tabeli ma wpływ na ich porządek fizyczny w warstwie pamięci? Tak.
To, czy to ważne, czy nie, to inna kwestia, na którą nie mogę (jeszcze) odpowiedzieć.
W sposób podobny do opisanego w często łączonym artykule Paula Randala na temat anatomii rekordu , spójrzmy na prostą tabelę dwóch kolumn z DBCC IND:
SET STATISTICS IO OFF;
SET STATISTICS TIME OFF;
USE master;
GO
IF DATABASEPROPERTY (N'RowStructure', 'Version') > 0 DROP DATABASE RowStructure;
GO
CREATE DATABASE RowStructure;
GO
USE RowStructure;
GO
CREATE TABLE FixedLengthOrder
(
c1 INT IDENTITY(1,1) PRIMARY KEY CLUSTERED
, c2 CHAR(10) DEFAULT REPLICATE('A', 10) NOT NULL
, c3 CHAR(10) DEFAULT REPLICATE('B', 10) NOT NULL
);
GO
INSERT FixedLengthOrder DEFAULT VALUES;
GO
DBCC IND ('RowStructure', 'FixedLengthOrder', 1);
GO
Powyższy wynik pokazuje, że musimy spojrzeć na stronę 89:
DBCC TRACEON (3604);
GO
DBCC PAGE ('RowStructure', 1, 89, 3);
GO
Na wyjściu z STRONY DBCC widzimy c1 wypchany znakiem „A” przed „B” c2:
Memory Dump @0x000000000D25A060
0000000000000000: 10001c00 01000000 41414141 41414141 †........AAAAAAAA
0000000000000010: 41414242 42424242 42424242 030000††††AABBBBBBBBBB...
I tylko dlatego, że pozwala otworzyć biust RowStructure.mdf
za pomocą edytora szesnastkowego i potwierdzić, że ciąg „A” poprzedza ciąg „B”:
Teraz powtórz test, ale odwróć kolejność ciągów, umieszczając znaki „B” w c1 i znaki „A” w c2:
CREATE TABLE FixedLengthOrder
(
c1 INT IDENTITY(1,1) PRIMARY KEY CLUSTERED
, c2 CHAR(10) DEFAULT REPLICATE('B', 10) NOT NULL
, c3 CHAR(10) DEFAULT REPLICATE('A', 10) NOT NULL
);
GO
Tym razem nasze wyjście DBCC PAGE jest inne i ciąg „B” pojawia się jako pierwszy:
Memory Dump @0x000000000FC2A060
0000000000000000: 10001c00 01000000 42424242 42424242 †........BBBBBBBB
0000000000000010: 42424141 41414141 41414141 030000††††BBAAAAAAAAAA...
Ponownie, tylko na chichoty, sprawdźmy zrzut heksadecymalny pliku danych:
Jak wyjaśnia anatomia rekordu , kolumny rekordu o stałej i zmiennej długości są przechowywane w odrębnych blokach. Logicznie przeplatane stałe i zmienne typy kolumn nie mają wpływu na zapis fizyczny. Jednak w każdym bloku kolejność kolumn jest odwzorowana na kolejność bajtów w pliku danych.
CREATE TABLE FixedAndVariableColumns
(
c1 INT IDENTITY(1,1) PRIMARY KEY CLUSTERED
, c2 CHAR(10) DEFAULT REPLICATE('A', 10) NOT NULL
, c3 VARCHAR(10) DEFAULT REPLICATE('B', 10) NOT NULL
, c4 CHAR(10) DEFAULT REPLICATE('C', 10) NOT NULL
, c5 VARCHAR(10) DEFAULT REPLICATE('D', 10) NOT NULL
, c6 CHAR(10) DEFAULT REPLICATE('E', 10) NOT NULL
);
GO
Memory Dump @0x000000000E07C060
0000000000000000: 30002600 01000000 41414141 41414141 †0.&.....AAAAAAAA
0000000000000010: 41414343 43434343 43434343 45454545 †AACCCCCCCCCCEEEE
0000000000000020: 45454545 45450600 00020039 00430042 †EEEEEE.....9.C.B
0000000000000030: 42424242 42424242 42444444 44444444 †BBBBBBBBBDDDDDDD
0000000000000040: 444444†††††††††††††††††††††††††††††††DDD
Zobacz też:
Kolejność kolumn nie ma znaczenia… ogólnie, ale - ZALEŻY!
CREATE TABLE
instrukcją (z wyjątkiem tego, że kolumny klucza CI są pierwsze w sekcji). Chociaż kolejność kolumn może ulec zmianie, jeśliALTER COLUMN
zmieni się typy danych / długości kolumn. Jedyny drobny przypadek, w którym ma znaczenie, o którym mogę myśleć, to to, że kolumny na końcu sekcji o zmiennej długości z pustym łańcuchem lub wartością NULL nie zajmują wcale miejsca w tablicy przesunięć kolumn (wykazane przez Kalen Delaney w książce dotyczącej elementów wewnętrznych z 2008 r.)C
nie pasują i przechodzą na własną rozszerzoną stronę. Zatemselect A, B
z YourTable` wymaga tylko połowa odczytów stronyselect A, C from YourTable
."Whether it matters or not is a different issue that I can't answer (yet)."
: Kolejność kolumn może znacząco wpływać na wydajność, a nawet wpływać na błędy! Sprawdź to - Demo 2 pokazuje to lepiej, myślęJeśli nie zdefiniujesz indeksu klastrowego, otrzymasz tabelę sterty. W przypadku tabeli stert zawsze będziesz skanować podczas odczytu danych, a tym samym zostaną odczytane całe wiersze, co sprawi, że kolejność kolumn stanie się kwestią sporną.
Jak tylko zdefiniujesz indeks klastrowy, dane są fizycznie przestawiane w celu dostosowania do fizycznej kolejności kolumn, jak określisz - i w tym momencie kolejność fizyczna staje się ważna. Porządek fizyczny decyduje o kwalifikowalności operatora szukającego na podstawie używanych predykatów.
Chociaż nigdzie nie pamiętam, by go czytać, zakładam, że SQL Server nie gwarantuje fizycznej kolejności kolumn dla stosów, podczas gdy będzie to gwarantowane dla indeksów. Aby odpowiedzieć na twoje pytanie, nie, kolejność kolumn w definicji nie powinna mieć znaczenia, ponieważ nie będą miały znaczenia podczas odczytu danych (pamiętaj, że jest to tylko hałd - indeksy to inna sprawa).
Aktualizacja
Właściwie zadajesz dwa pytania - „czy logiczne uporządkowanie kolumn w tabeli ma wpływ na ich fizyczne uporządkowanie w warstwie pamięci” jest nie. Kolejność logiczna, zgodnie z definicją metadanych, nie musi być w tej samej kolejności, co fizyczna. Zbieram, że szukam odpowiedzi na to, czy logiczny porządek w tabeli TWORZENIA STABILNOŚCI skutkuje tym samym porządkiem fizycznym przy tworzeniu - czego nie znam na stosach - chociaż z powyższym zastrzeżeniem.
źródło
Na podstawie tego, co widziałem i czytałem, porządkowanie kolumn w SQL Server nie ma znaczenia. Mechanizm pamięci masowej umieszcza kolumny w wierszu niezależnie od tego, jak są określone w instrukcji CREATE TABLE. Biorąc to pod uwagę, jestem pewien, że istnieją pewne bardzo odosobnione przypadki brzegowe, w których ma to znaczenie, ale myślę, że będzie ci trudno uzyskać jedną ostateczną odpowiedź na te pytania. „ Inside The Storage Engine ” Paula Randala„Kategoria postów na blogu jest najlepszym źródłem wszystkich szczegółów na temat tego, jak działa silnik pamięci, o których wiem. Myślę, że musiałbyś przestudiować wszystkie różne sposoby działania magazynu i matrycę w porównaniu do wszystkich przypadków użycia aby znaleźć przypadki krawędzi, w których kolejność miałaby znaczenie. O ile nie wskazano konkretnego przypadku krawędzi, który dotyczy mojej sytuacji, po prostu logicznie porządkuję kolumny w moim CREATE TABLE. Mam nadzieję, że to pomoże.
źródło
Rozumiem co masz na myśli. Z perspektywy projektowania tabela wygląda następująco:
jest o wiele lepszy niż stół, który wygląda następująco:
Ale aparat bazy danych tak naprawdę nie przejmuje się logiczną kolejnością kolumn, jeśli wydasz tsql w ten sposób:
Mechanizm po prostu wie, gdzie znajduje się lista FirstName na dysku.
źródło