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


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.