ভারচার (এন) এর ওভারহেড কী?


15

আমি থেকে এই টুকরা অর্থ জন্য জিজ্ঞাসা করতে চেয়েছিলেন Postgres ডক সংক্রান্ত 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)হয় ফাঁকা-padded 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-বাইট STRING 'foo বিন্যাস' দখল করে 4 বাইট ডিস্কে এবং 7 বাইট র্যাম (তাই 1 বনাম বাইট 4 ওভারহেড এর বাইটস) হবে।
  • 140 বাইট স্ট্রিং '123 ...' ডিস্কে এবং র‌্যামে 144 বাইট দখল করে (তাই সর্বদা ওভারহেডের 4 বাইট)।
  • সঞ্চয়ের integerকোনও ওভারহেড নেই (তবে এটির প্রান্তিককরণের প্রয়োজনীয়তা রয়েছে যা প্যাডিং আরোপ করতে পারে)।
  • সারিটিতে টিউপল শিরোলেখের জন্য 24 বাইটের অতিরিক্ত ওভারহেড রয়েছে (পৃষ্ঠা শিরোনামের আইটেম পয়েন্টারটির জন্য পিছু প্রতি অতিরিক্ত 4 বাইট)।
  • এবং সর্বশেষে তবে সর্বনিম্ন নয়: ছোটটির ওভারহেডটি varcharকেবল 1 বাইটের মধ্যে থাকে যদিও এটি সারি থেকে বের করা হয়নি - সারি আকার থেকে দেখা যায়। (এ কারণেই পুরো সারিগুলি নির্বাচন করা মাঝে মাঝে কিছুটা দ্রুত।

সম্পর্কিত:


1
1 বাইট ওভারহেড কি এখনও 1 বাইট ইনডেক্সে রয়েছে?
— dvtan

1
@dtgq: একটি সূচক কেবল একটি টেবিলের মতো ডেটা সঞ্চয় করে, তাই হ্যাঁ।
— এরউইন ব্র্যান্ডসটেটার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.