Sqlserver
 sql >> डेटाबेस >  >> RDS >> Sqlserver

क्या मुझे इनलाइन वर्कर (अधिकतम) कॉलम का उपयोग करना चाहिए या इसे एक अलग टेबल में स्टोर करना चाहिए?

इसे इनलाइन रखें। कवर के तहत SQL सर्वर पहले से ही MAX कॉलम को SQL 2005 से एक अलग 'आवंटन इकाई' में संग्रहीत करता है। तालिका और अनुक्रमणिका संगठन देखें। यह वास्तव में MAX कॉलम को अपनी तालिका में रखने जैसा ही है, लेकिन स्पष्ट रूप से ऐसा करने का कोई नुकसान नहीं है।

स्पष्ट तालिका का होना वास्तव में धीमा दोनों होगा (विदेशी कुंजी बाधा के कारण) और अधिक स्थान का उपभोग करें (DetaiID दोहराव के कारण)। यह उल्लेख करने के लिए नहीं कि इसके लिए अधिक कोड की आवश्यकता है, और बग... कोड लिखकर पेश किए जाते हैं।

वैकल्पिक पाठ http://i.msdn.microsoft.com/ms189051.3be61595-d405-4b30-9794-755842d7db7e(en-us,SQL.100).gif

अपडेट करें

डेटा के वास्तविक स्थान की जांच करने के लिए, एक साधारण परीक्षण इसे दिखा सकता है:

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%% छद्म स्तंभ पंक्ति का वास्तविक भौतिक स्थान दिखाएगा, मेरे मामले में यह पृष्ठ 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)   

टेक्स्ट और NTEXT को छोड़कर सभी कॉलम मान MAX प्रकारों सहित इनलाइन संग्रहीत किए गए थे।
तालिका विकल्पों को बदलने और एक नई पंक्ति सम्मिलित करने के बाद (sp_tableoption मौजूदा पंक्तियों को प्रभावित नहीं करता), MAX प्रकारों को उनके स्वयं के संग्रहण में बेदखल कर दिया गया था:

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);

ध्यान दें कि कैसे m_a और nm_a कॉलम अब 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)                    

पूर्णता के लिए हम गैर-अधिकतम क्षेत्रों में से एक को पंक्ति से बाहर करने के लिए बाध्य कर सकते हैं:

update a set v_a = replicate('X', 8000);
dbcc page(2,1, 200, 3);

नोट करें कि कैसे v_a कॉलम को रो-ओवरफ्लो स्टोरेज में स्टोर किया जाता है:

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) 

इसलिए, जैसा कि अन्य पहले ही टिप्पणी कर चुके हैं, MAX प्रकार डिफ़ॉल्ट रूप से इनलाइन संग्रहीत किए जाते हैं, यदि वे फिट होते हैं। कई डीडब्ल्यू परियोजनाओं के लिए यह अस्वीकार्य होगा क्योंकि सामान्य डीडब्ल्यू लोड को स्कैन करना चाहिए या कम से कम रेंज स्कैन करना चाहिए, इसलिए sp_tableoption ..., 'large value types out of row', '1' इस्तेमाल किया जाना चाहिए। ध्यान दें कि यह मौजूदा पंक्तियों को प्रभावित नहीं करता है, मेरे परीक्षण में इंडेक्स पुनर्निर्माण पर भी नहीं , इसलिए विकल्प को जल्दी चालू करना होगा।

अधिकांश OLTP प्रकार के लोड के लिए हालांकि तथ्य यह है कि यदि संभव हो तो MAX प्रकारों को इनलाइन संग्रहीत किया जाता है, वास्तव में एक फायदा है, क्योंकि OLTP एक्सेस पैटर्न तलाश करना है और पंक्ति की चौड़ाई उस पर बहुत कम प्रभाव डालती है।

मूल प्रश्न के संबंध में कोई कम नहीं:अलग तालिका आवश्यक नहीं है। large value types out of row को चालू करना विकल्प विकास/परीक्षण के लिए मुफ्त लागत पर समान परिणाम प्राप्त करता है।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL में न्यूनतम दो मान प्राप्त करना

  2. SQL सर्वर 2012 सर्विस पैक 1 और संचयी अद्यतन 1

  3. गलत रचनाक्रम पास के ''

  4. डेटाबेस से सभी कनेक्शनों को समाप्त करने के लिए स्क्रिप्ट (RESTRICTED_USER ROLLBACK से अधिक)

  5. कंटेन्स () का उपयोग करते समय 2100 पैरामीटर सीमा (एसक्यूएल सर्वर) को मारना