แปลกใจที่คู่มือถูกต้อง แต่มีมากกว่านั้น
สำหรับหนึ่งขนาดบนดิสก์ (ในตารางแม้ในขณะที่ไม่ได้เก็บไว้บนดิสก์จริง) อาจแตกต่างจากขนาดในหน่วยความจำ บนดิสก์ค่าใช้จ่ายสำหรับvarchar
ค่าสั้นถึง 126 ไบต์จะลดลงเป็น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 ไบต์บนดิสก์และ7 ไบต์ใน RAM (ดังนั้น 1 ไบต์เทียบกับ 4 ไบต์ของค่าใช้จ่าย)
- สตริง 140 ไบต์ '123 ... ' ใช้เวลา 144 ไบต์ทั้งบนดิสก์และใน RAM (ดังนั้นจึงมีค่าใช้จ่าย 4 ไบต์เสมอ)
- การจัดเก็บของ
integer
ไม่มีค่าใช้จ่าย (แต่มีข้อกำหนดการจัดตำแหน่งที่สามารถกำหนดช่องว่างภายใน)
- แถวมีค่าใช้จ่ายเพิ่มเติม 24 ไบต์สำหรับส่วนหัว tuple (บวก 4 ไบต์เพิ่มเติมต่อ tuple สำหรับตัวชี้รายการในส่วนหัวของหน้า)
- และสุดท้าย แต่ไม่ท้ายสุด: ค่าโสหุ้ยของขนาดเล็ก
varchar
ยังคงเป็นเพียง 1 ไบต์ในขณะที่ยังไม่ได้แยกออกจากแถว - ดังที่เห็นได้จากขนาดแถว (นั่นเป็นเหตุผลที่บางครั้งมันเร็วกว่าเล็กน้อยในการเลือกทั้งแถว)
ที่เกี่ยวข้อง: