Влияет ли логическое расположение столбцов в таблице на их физический порядок на уровне хранения? Да.
Имеет ли это значение или нет, это другой вопрос, на который я не могу ответить (пока).
Аналогично тому, как описано в часто цитируемой статье Пола Рэндала об анатомии записи , давайте рассмотрим простую таблицу из двух столбцов с 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
Вывод выше показывает, что нам нужно взглянуть на страницу 89:
DBCC TRACEON (3604);
GO
DBCC PAGE ('RowStructure', 1, 89, 3);
GO
В выводе из DBCC PAGE мы видим, что c1 заполнен символом «A» перед «b» c2:
Memory Dump @0x000000000D25A060
0000000000000000: 10001c00 01000000 41414141 41414141 †........AAAAAAAA
0000000000000010: 41414242 42424242 42424242 030000††††AABBBBBBBBBB...
И только потому, что давайте откроем бюст RowStructure.mdf
с помощью шестнадцатеричного редактора и подтвердим, что строка «A» предшествует строке «B»:
Теперь повторите тест, но измените порядок строк, поместив символы «B» в c1 и символы «A» в 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
На этот раз наш вывод DBCC PAGE отличается, и строка 'B' появляется первой:
Memory Dump @0x000000000FC2A060
0000000000000000: 10001c00 01000000 42424242 42424242 †........BBBBBBBB
0000000000000010: 42424141 41414141 41414141 030000††††BBAAAAAAAAAA...
Опять же, просто для смеха, давайте проверим шестнадцатеричный дамп файла данных:
Как объясняет Анатомия Записи , столбцы фиксированной и переменной длины записи хранятся в отдельных блоках. Логическое чередование фиксированных и переменных типов столбцов не имеет никакого отношения к физической записи. Однако в каждом блоке порядок ваших столбцов соответствует порядку байтов в файле данных.
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
Смотрите также:
Порядок столбцов не имеет значения ... в общем, но - ЭТО ЗАВИСИТ!
CREATE TABLE
инструкции (за исключением того, что ключевые столбцы CI стоят первыми в разделе). Хотя порядок столбцов может измениться, еслиALTER COLUMN
изменится тип данных / длина столбца. Единственный незначительный случай, когда мне кажется важным, это то, что столбцы в конце раздела переменной длины с пустой строкой или NULL вообще не занимают места в массиве смещений столбцов (продемонстрировано Kalen Delaney в книге внутренних данных 2008 года)