sql >> Databáze >  >> RDS >> Sqlserver

Mám použít vložený sloupec varchar(max) nebo jej uložit do samostatné tabulky?

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.



  1. Kvíz o výkonu a ladění Oracle

  2. VLDB ve věku 20 let:Budete potřebovat větší…

  3. Typ tabulky v příkladu Oracle PL SQL

  4. Jak použít typ tabulky v příkazu SELECT FROM?