Nechte to v souladu. Pod krytem SQL Server již od SQL 2005 ukládá sloupce MAX v samostatné „alokační jednotce“. Viz Organizace tabulek a indexů. To je ve skutečnosti úplně stejné jako ponechání sloupce MAX v jeho vlastní tabulce, ale bez jakékoli nevýhody explicitního provedení.
Explicitní tabulka by ve skutečnosti byla pomalejší (kvůli omezení cizího klíče) a zabírají více místa (kvůli duplikaci DetaiID). Nemluvě o tom, že to vyžaduje více kódu a chyby jsou zaváděny... psaním kódu.
alternativní text http://i.msdn.microsoft.com/ms189051.3be61595-d405-4b30-9794-755842d7db7e(en-us,SQL.100).gif
Aktualizovat
Chcete-li zkontrolovat skutečné umístění dat, může je ukázat jednoduchý test:
use tempdb;
go
create table a (
id int identity(1,1) not null primary key,
v_a varchar(8000),
nv_a nvarchar(4000),
m_a varchar(max),
nm_a nvarchar(max),
t text,
nt ntext);
go
insert into a (v_a, nv_a, m_a, nm_a, t, nt)
values ('v_a', N'nv_a', 'm_a', N'nm_a', 't', N'nt');
go
select %%physloc%%,* from a
go
%%physloc%%
pseudo sloupec zobrazí skutečné fyzické umístění řádku, v mém případě to byla stránka 200:
dbcc traceon(3604)
dbcc page(2,1, 200, 3)
Slot 0 Column 2 Offset 0x19 Length 3 Length (physical) 3
v_a = v_a
Slot 0 Column 3 Offset 0x1c Length 8 Length (physical) 8
nv_a = nv_a
m_a = [BLOB Inline Data] Slot 0 Column 4 Offset 0x24 Length 3 Length (physical) 3
m_a = 0x6d5f61
nm_a = [BLOB Inline Data] Slot 0 Column 5 Offset 0x27 Length 8 Length (physical) 8
nm_a = 0x6e006d005f006100
t = [Textpointer] Slot 0 Column 6 Offset 0x2f Length 16 Length (physical) 16
TextTimeStamp = 131137536 RowId = (1:182:0)
nt = [Textpointer] Slot 0 Column 7 Offset 0x3f Length 16 Length (physical) 16
TextTimeStamp = 131203072 RowId = (1:182:1)
Všechny hodnoty sloupců kromě TEXT a NTEXT byly uloženy inline, včetně typů MAX.
Po změně možností tabulky a vložení nového řádku (sp_tableoption neovlivňuje existující řádky) byly typy MAX vyřazeny do vlastního úložiště:
sp_tableoption 'a' , 'large value types out of row', '1';
insert into a (v_a, nv_a, m_a, nm_a, t, nt)
values ('2v_a', N'2nv_a', '2m_a', N'2nm_a', '2t', N'2nt');
dbcc page(2,1, 200, 3);
Všimněte si, že sloupce m_a a nm_a jsou nyní textovým ukazatelem do alokační jednotky LOB:
Slot 1 Column 2 Offset 0x19 Length 4 Length (physical) 4
v_a = 2v_a
Slot 1 Column 3 Offset 0x1d Length 10 Length (physical) 10
nv_a = 2nv_a
m_a = [Textpointer] Slot 1 Column 4 Offset 0x27 Length 16 Length (physical) 16
TextTimeStamp = 131268608 RowId = (1:182:2)
nm_a = [Textpointer] Slot 1 Column 5 Offset 0x37 Length 16 Length (physical) 16
TextTimeStamp = 131334144 RowId = (1:182:3)
t = [Textpointer] Slot 1 Column 6 Offset 0x47 Length 16 Length (physical) 16
TextTimeStamp = 131399680 RowId = (1:182:4)
nt = [Textpointer] Slot 1 Column 7 Offset 0x57 Length 16 Length (physical) 16
TextTimeStamp = 131465216 RowId = (1:182:5)
Pro úplnost můžeme také vytlačit jedno z nemax polí z řádku:
update a set v_a = replicate('X', 8000);
dbcc page(2,1, 200, 3);
Všimněte si, jak je sloupec v_a uložen v úložišti Row-Overflow:
Slot 0 Column 1 Offset 0x4 Length 4 Length (physical) 4
v_a = [BLOB Inline Root] Slot 0 Column 2 Offset 0x19 Length 24 Length (physical) 24
Level = 0 Unused = 99 UpdateSeq = 1
TimeStamp = 1098383360
Link 0
Size = 8000 RowId = (1:176:0)
Takže, jak již uvedli jiní, typy MAX jsou standardně uloženy inline, pokud se hodí. Pro mnoho projektů DW by to bylo nepřijatelné, protože typické zatížení DW musí skenovat nebo alespoň skenovat rozsah, takže sp_tableoption ..., 'large value types out of row', '1'
by měl být použit. Všimněte si, že to neovlivňuje existující řádky, v mém testu ani při opětovném sestavení indexu , takže možnost musí být zapnuta brzy.
Pro většinu načtení typu OLTP je však skutečnost, že typy MAX jsou pokud možno uloženy inline, ve skutečnosti výhodou, protože přístupový vzor OLTP má hledat a šířka řádku na něj má malý vliv.
Nicméně, pokud jde o původní otázku:samostatná tabulka není nutná. Zapnutí large value types out of row
Možnost dosahuje stejného výsledku za bezplatné náklady na vývoj/test.