Varchar (n) के लिए ओवरहेड क्या है?


15

मैं पोस्टग्रेज डॉक से इस टुकड़े के अर्थ के बारे में पूछना चाहता था varchar(n):

एक छोटी स्ट्रिंग (126 बाइट तक) के लिए भंडारण की आवश्यकता 1 बाइट से अधिक वास्तविक स्ट्रिंग है, जिसमें चरित्र के मामले में स्पेस पेडिंग शामिल है। लंबे तार में 1 के बजाय ओवरहेड के 4 बाइट्स होते हैं।

मान लेते हैं कि मेरे पास एक varchar(255)मैदान है। और अब, निम्नलिखित कथन:

  • यदि यह फ़ील्ड 10 बाइट्स की स्ट्रिंग रखती है, तो ओवरहेड 1 बाइट है। तो स्ट्रिंग 11 बाइट्स का उपयोग करेगी।
  • यदि फ़ील्ड 140 बाइट्स का उपयोग करके स्ट्रिंग रखती है, तो ओवरहेड 4 बाइट्स है। तो स्ट्रिंग 144 बाइट्स का उपयोग करेगा।

क्या वे कथन सत्य से ऊपर हैं? यहाँ कोई भी डॉक को मेरे जैसा ही समझता है लेकिन यहाँ कोई कहता है कि ओवरहेड हमेशा यहाँ 4 बाइट्स होता है ?

जवाबों:


19

दुर्भाग्य से, मैनुअल सही है। लेकिन इसके साथ बहुत कुछ है।

एक के लिए, डिस्क पर आकार (किसी भी तालिका में , तब भी जब वास्तव में डिस्क पर संग्रहीत नहीं किया जाता है) स्मृति में आकार से भिन्न हो सकता है । डिस्क पर, varchar126 बाइट्स तक के छोटे मानों के लिए ओवरहेड को मैनुअल में बताए अनुसार 1 बाइट तक घटाया जाता है । लेकिन स्मृति में ओवरहेड हमेशा 4 बाइट्स (एक बार व्यक्तिगत मान निकाले जाने के बाद) होता है।

उसी के लिए सच है text, varchar, varchar(n)याchar(n) - सिवाय इसके कि char(n)है करने के लिए खाली-गद्देदार nअक्षर और आप सामान्य रूप से इसका इस्तेमाल नहीं करना चाहती। इसका प्रभावी आकार अभी भी मल्टी-बाइट एन्कोडिंग में भिन्न हो सकता है क्योंकि nअधिकतम वर्णों को दर्शाता है, बाइट्स नहीं:

nलंबाई में वर्ण (बाइट्स नहीं) तक स्ट्रिंग्स ।

वे सभी varlenaआंतरिक रूप से उपयोग करते हैं।
"char"(डबल-कोट्स के साथ) एक अलग प्राणी है और हमेशा एक ही बाइट लेता है।
अनटिप्ड स्ट्रिंग लिटरल्स ( 'foo') में एक सिंगल बाइट ओवरहेड होता है। टाइप किए गए मूल्यों के साथ भ्रमित होने की नहीं!

के साथ टेस्ट करें pg_column_size()

CREATE TEMP TABLE t (id int, v_small varchar, v_big varchar);
INSERT INTO t VALUES (1, 'foo', '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890');

SELECT pg_column_size(id)        AS id
     , pg_column_size(v_small)   AS v_small
     , pg_column_size(v_big)     AS v_big
     , pg_column_size(t)         AS t
FROM   t
UNION ALL  -- 2nd row measuring values in RAM
SELECT pg_column_size(1)
     , pg_column_size('foo'::varchar)
     , pg_column_size('12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890'::varchar)
     , pg_column_size(ROW(1, 'foo'::varchar, '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890'::varchar));

 id | v_small | v_big |  t
----+---------+-------+-----
  4 |       4 |   144 | 176
  4 |       7 |   144 | 176

जैसा कि आप देख सकते हैं:

  • 3-बाइट स्ट्रिंग 'foo' में डिस्क पर 4 बाइट्स और RAM में 7 बाइट्स (इसलिए 1 बाइट बनाम ओवरहेड के 4 बाइट्स) हैं।
  • 140-बाइट स्ट्रिंग '123 ...' डिस्क पर और रैम में 144 बाइट्स पर रहती है (इसलिए हमेशा ओवरहेड के 4 बाइट्स)।
  • भंडारण का integerकोई ओवरहेड नहीं है (लेकिन इसमें संरेखण आवश्यकताएँ हैं जो पैडिंग लगा सकती हैं)।
  • पंक्ति में टपल हेडर के लिए 24 बाइट्स का अतिरिक्त ओवरहेड है (पेज हेडर में आइटम पॉइंटर के लिए एक अतिरिक्त 4 बाइट्स प्रति ट्यूपल)।
  • और आखिरी लेकिन कम से कम नहीं: छोटे varcharका ओवरहेड अभी भी सिर्फ 1 बाइट है, जबकि इसे पंक्ति से नहीं निकाला गया है - जैसा कि पंक्ति आकार से देखा जा सकता है। (इसीलिए कभी-कभी पूरी पंक्तियों का चयन करना थोड़ा तेज़ होता है।)

सम्बंधित:


1
क्या इंडेक्स में अभी भी 1 बाइट ओवरहेड है?
दत्तन

1
@dtgq: एक इंडेक्स डेटा को टेबल की तरह स्टोर करता है, इसलिए हां।
इरविन ब्रान्डसेट्टर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.