it-swarm-eu.dev

Záleží na pořadí sloupců v definici tabulky?

Při definování tabulky je užitečné uspořádat sloupce v logických skupinách a samotné skupiny podle účelu. Logické řazení sloupců v tabulce předává vývojáři význam a je prvkem dobrého stylu.

To je jasné.

Není však jasné, zda logické řazení sloupců v tabulce má nějaký dopad na jejich fyzické uspořádání ve vrstvě úložiště, nebo zda má jakýkoli další dopad, o který by se člověk mohl zajímat.

Nezáleží na pořadí sloupců, kromě vlivu na styl?

Existuje otázka na Stack Overflow o tom, ale postrádá autoritativní odpověď.

35
Nick Chammas

Má logické řazení sloupců v tabulce nějaký dopad na jejich fyzické pořadí ve vrstvě úložiště? Ano.

Zda to záleží nebo ne, je jiný problém, na který nemohu odpovědět (zatím).

Podobným způsobem, jaký je popsán v často propojeném článku Paula Randala o anatomii záznam , pojďme se podívat na jednoduchou tabulku se dvěma sloupci s 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

DBCC IND output

Výše uvedený výstup ukazuje, že se musíme podívat na stránku 89:

DBCC TRACEON (3604);
GO
DBCC PAGE ('RowStructure', 1, 89, 3);
GO

Ve výstupu z DBCC PAGE vidíme c1 plněné znakem 'A' před c2 'B':

Memory Dump @0x000000000D25A060

0000000000000000:   10001c00 01000000 41414141 41414141 †........AAAAAAAA
0000000000000010:   41414242 42424242 42424242 030000††††AABBBBBBBBBB...

A jen proto, umožňuje nechat otevřít RowStructure.mdf pomocí hex editoru a potvrďte, že řetězec 'A' předchází řetězec 'B':

AAAAAAAAAA

Nyní opakujte test, ale obráťte pořadí řetězců a umístěte znaky „B“ do c1 a znaky „A“ do 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

Tentokrát se náš výstup DBCC PAGE liší a řetězec 'B' se objeví jako první:

Memory Dump @0x000000000FC2A060

0000000000000000:   10001c00 01000000 42424242 42424242 †........BBBBBBBB 
0000000000000010:   42424141 41414141 41414141 030000††††BBAAAAAAAAAA... 

Opět, jen pro chichotání, můžete zkontrolovat hexadecimu datového souboru:

BBBBBBBBBB

Jak vysvětluje anatomie záznam , sloupce pevné a proměnné délky záznamu jsou uloženy v samostatných blocích. Logicky prokládané typy pevných a proměnných sloupců nemají žádný vliv na fyzický záznam. V každém bloku se však pořadí vašich sloupců mapuje na pořadí bytů v datovém souboru.

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

Viz také:

Pořadí sloupců nezáleží ... obecně, ale - ZÁVISÍ!

23

Pokud nedefinujete seskupený index, dostanete tabulku haldy. U haldy tabulky budete vždy skenovat při čtení dat, a tak se přečtou celé řádky, čímž se pořadí sloupců stane bodem.

Jakmile definujete seskupený index, budou data fyzicky přeskupena tak, aby odpovídala fyzickému pořadí sloupců, jak určíte - a v tomto bodě bude fyzický řád důležitý. Fyzické pořadí je to, co určuje způsobilost vyhledávajícího operátora na základě predikátů, které používáte.

I když si nemůžu vzpomenout, že bych si ji kdekoli přečetl, předpokládal bych, že SQL Server nezaručuje fyzické pořadí sloupců pro haldy, zatímco to bude zaručeno pro indexy. Chcete-li odpovědět na vaši otázku, ne, na pořadí sloupců v definici by nemělo záležet, protože na nich nezáleží při čtení dat (toto je pouze pro hromady - indexy jsou jiná záležitost) .

Aktualizace
Vlastně se ptáte dvou otázek - „zda logické řazení sloupců v tabulce má vliv na jejich fyzické uspořádání ve vrstvě úložiště“ je ne. Logické pořadí definované metadaty nemusí být ve stejném pořadí jako fyzické. Shromažďuji, že hledáš odpověď na to, zda logické pořadí v CREATE TABLE vede ke stejnému fyzickému pořadí při tvorbě - což nevím, pro hromady - i když s výpovědí výše.

7

Na základě toho, co jsem viděl a přečetl, pořadí sloupců v SQL Server nezmění. Úložný modul umisťuje sloupce do řádku bez ohledu na to, jak jsou určeny v příkazu CREATE TABLE. Jak už bylo řečeno, jsem si jistý, že existují velmi izolované případy Edge, ale na to si myslím, že budete mít těžko dostat jedinou konečnou odpověď. Paul --- Randal's Inside The Storage Engine "blog kategorie příspěvků je nejlepším zdrojem pro všechny podrobnosti o tom, jak storage engine funguje, o kterém vím. Myslím, že budete muset studovat všechny různé způsoby, jak úložiště funguje a matice, které proti všem případům použití najít Edge případy, kde by záleželo na pořadí. Pokud není upřesněn konkrétní případ Edge, který se vztahuje na mou situaci, řádně objednávám sloupce logicky na svém CREATE TABLE. Doufám, že to pomůže.

2
Todd Everett

Chápu, co tím myslíš. Z pohledu designu tabulka, která vypadá takto:

**EMPLOYEES**
EmployeeID
FirstName
LastName
Birthday
SSN 

je mnohem lepší než tabulka, která vypadá takto:

**EMPLOYEES**
LastName
EmployeeID
SSN 
Birthday
FirstName

Databázový stroj se však opravdu nezajímá o vaše logické pořadí sloupců, pokud vydáte tsql jako je tento:

SELECT FirstName, LastName, SSN FROM Employees

Stroj jen ví, kde je seznam FirstName uložen na disku.

1
MarlonRibunal