ค่าคอลัมน์ที่ว่างเปล่าใช้พื้นที่เก็บข้อมูลเดียวกันกับค่าคอลัมน์ที่เต็มไปหรือไม่?


16

ฉันมีตารางที่มี 2 คอลัมน์ varchar(38)ประเภทของคอลัมน์ทั้งมีการตั้งค่า ถ้าฉันสร้างแถวที่มีค่าว่างสำหรับคอลัมน์ใดคอลัมน์หนึ่งจะใช้พื้นที่เก็บข้อมูลเดียวกันหรือไม่ถ้าค่านั้นไม่ว่างเปล่า?

กล่าวอีกนัยหนึ่ง MySQL จะจองพื้นที่เก็บข้อมูลสำหรับคอลัมน์ (ขึ้นอยู่กับประเภท) เมื่อสร้างแถวหรือไม่

คำตอบ:


11

จากโครงสร้างแถวทางกายภาพ Innodb กระสุนปืน # 7 ภายใต้ REDUNDANT ROW_FORMAT

ค่า NULL ของ SQL จะสำรองหนึ่งหรือสองไบต์ในไดเรกทอรีบันทึก นอกจากนั้นสำรองค่า SQL โมฆะศูนย์ไบต์ในส่วนของการบันทึกข้อมูลถ้าเก็บไว้ในคอลัมน์ยาวตัวแปร ในคอลัมน์ความยาวคงที่มันจะสงวนความยาวคงที่ของคอลัมน์ในส่วนข้อมูลของเรกคอร์ด การจองพื้นที่คงที่สำหรับค่า NULL เปิดใช้งานการอัพเดตคอลัมน์จากค่า NULL เป็นค่าที่ไม่ใช่ค่า NULL ที่ต้องทำโดยไม่ทำให้เกิดการแตกแฟรกเมนต์ของหน้าดัชนี

จากโครงสร้างแถวทางกายภาพ Innodb กระสุนปืนหมายเลข 2 ภายใต้ COMPACT ROW_FORMAT

ส่วนความยาวผันแปรของส่วนหัวของบันทึกประกอบด้วยบิตเวกเตอร์สำหรับการระบุคอลัมน์ NULL หากจำนวนของคอลัมน์ในดัชนีที่สามารถเป็นโมฆะเป็นเอ็นบิตเวกเตอร์ตรงบริเวณเพดาน (N / 8) ไบต์ (ตัวอย่างเช่นหากมีที่ใดก็ได้จาก 9 ถึง 15 คอลัมน์ที่สามารถเป็น NULL ได้บิตเวคเตอร์ใช้สองไบต์)คอลัมน์ที่เป็น NULL จะไม่ใช้พื้นที่อื่นนอกเหนือจากบิตในเวกเตอร์นี้ ส่วนความยาวตัวแปรของส่วนหัวยังมีความยาวของคอลัมน์ความยาวตัวแปร แต่ละความยาวใช้เวลาหนึ่งหรือสองไบต์ขึ้นอยู่กับความยาวสูงสุดของคอลัมน์ ถ้าคอลัมน์ทั้งหมดในดัชนีไม่ใช่ NULL และมีความยาวคงที่ส่วนหัวของเรกคอร์ดจะไม่มีส่วนที่มีความยาวผันแปรได้

ตาม bulletpoint เหล่านี้นี่คือสิ่งที่NULLค่าใช้สำหรับการจัดเก็บของคอลัมน์

  • ความยาวของตัวแปร: ค่า NULL จะไม่มีหน่วยเก็บในแถว
  • ความยาวคงที่: ใช้พื้นที่ที่สงวนไว้

ตอนนี้คุณต้องตัดสินใจระหว่างการใช้งาน CHAR และ VARCHAR เพราะสิ่งที่จุดแรกนำออกมา

การจองพื้นที่คงที่สำหรับค่า NULL ช่วยให้สามารถอัปเดตคอลัมน์จากค่า NULL เป็นค่าที่ไม่ใช่ค่า NULL ที่ต้องทำโดยไม่ทำให้เกิดการแยกส่วนของหน้าดัชนี

การทำเช่นนี้จะช่วยป้องกันไม่ให้มีการกระจายตัวของแถวใดก็ตามที่ไปตามถนนเมื่อจัดเก็บข้อมูลที่ไม่ใช่ NULL นี่คือสิ่งที่ฉันได้พูดคุยก่อนหน้านี้เกี่ยวกับ MyISAM: ดูโพสต์เก่าของฉันประสิทธิภาพการทำงานของการใช้ CHAR vs VARCHAR ในฟิลด์ขนาดคงที่คืออะไร .


สวัสดี Rolando มีรายการอื่นที่ฉันลืมพูดถึงความแตกต่างในการจัดสรรหน่วยความจำระหว่างการประกาศประเภท varchar (5) และ varchar (100) หรือโทษที่เกิดขึ้นจริงจากการจัดสรรเกิน
Craig Efrein

@CraigEfrein แน่นอนคุณควรเพิ่มการจัดสรรหน่วยความจำที่คำตอบของคุณ (BTW ฉันได้เพิ่มคำตอบของคุณแล้ว)
RolandoMySQLDBA

1
บทลงโทษสำหรับการจัดสรรเกินเกิดขึ้นเมื่อคุณมีความซับซ้อนSELECTที่จำเป็นต้องสร้างตารางชั่วคราว ถ้าเป็นไปได้ก็จะใช้MEMORYและแปลงVARCHARไปCHARสำหรับตารางแฟ้ม tmp ตอนนี้VARCHAR(100)รับค่าคงที่ 100 (หรือ 300) ไบต์ซึ่งอาจทำให้การสืบค้นช้าลง
Rick James

@RolandoMySQLDBA เป็นพฤติกรรมที่อธิบายไว้ในคำตอบของคุณที่ใช้กับ Mysql 5.7 รูปแบบแถวแบบไดนามิกและขนาดกะทัดรัด
Dinesh Kumar

@DineshKumar ย่อหน้าเหล่านี้ยังคงอยู่ในเอกสาร 5.7 / 8.0 โปรดอ้างอิงถึงdev.mysql.com/doc/refman/5.7/en/innodb-row-format-dynamic.htmlสำหรับ DYNAMIC
RolandoMySQLDBA

8

โดยไม่คำนึงถึงความยาวที่คุณกำหนดสำหรับคอลัมน์ varchar ของคุณพื้นที่เก็บข้อมูลที่ใช้โดยคอลัมน์ว่างจะเหมือนกัน

ประเภท CHAR และ VARCHAR

ป้อนคำอธิบายรูปภาพที่นี่

สิ่งนี้ระบุพื้นที่ที่ใช้โดยคอลัมน์ varchar เท่านั้นและไม่ได้พิจารณาพื้นที่เก็บข้อมูลทั้งหมดที่ใช้โดยแถวดัชนีดัชนีคีย์หลักและคอลัมน์อื่น ๆ

เมื่อ ypercube กล่าวถึงในความคิดเห็นของเขามีข้อควรพิจารณาเพิ่มเติมสำหรับที่เก็บแถวโดยรวมเมื่อมีคอลัมน์ nullable อย่างน้อยหนึ่งคอลัมน์

โครงสร้างแถวทางกายภาพของ Innodb

ส่วนความยาวผันแปรของส่วนหัวของบันทึกมีบิตเวกเตอร์สำหรับการระบุคอลัมน์ NULL หากมีที่ใดก็ได้จาก 9 ถึง 15 คอลัมน์ที่สามารถเป็น NULL ได้บิตเวกเตอร์ใช้สองไบต์)

...

ส่วนความยาวตัวแปรของส่วนหัวยังมีความยาวของคอลัมน์ความยาวตัวแปร แต่ละความยาวใช้เวลาหนึ่งหรือสองไบต์ขึ้นอยู่กับความยาวสูงสุดของคอลัมน์ ถ้าคอลัมน์ทั้งหมดในดัชนีไม่ใช่ NULL และมีความยาวคงที่ส่วนหัวของเรกคอร์ดจะไม่มีส่วนที่มีความยาวผันแปรได้

และใช่พื้นที่เก็บข้อมูลที่ใช้มีการเปลี่ยนแปลงตามประเภทที่คุณเลือกไม่ว่าจะเป็นแบบคงที่หรือตัวแปรการเปรียบเทียบและปัจจัยอื่น ๆ เช่นเครื่องยนต์

MySQL ให้คำแนะนำในการเพิ่มประสิทธิภาพการจัดเก็บข้อมูลที่นี่: การปรับขนาดข้อมูลให้เหมาะสม

ปรับปรุง

ข้อควรพิจารณาเพิ่มเติมอีกอย่างหนึ่งสำหรับ varchar และนั่นคือหน่วยความจำ เป็นสิ่งสำคัญใน MySQL ที่จะ จำกัด ขนาดของคอลัมน์ความยาวตัวแปรให้มากที่สุด แม้ว่าคอลัมน์จะเป็นตัวแปรและพื้นที่เก็บข้อมูลที่ใช้เป็นตัวแปร แต่ MySQL จะจัดสรรหน่วยความจำในกลุ่มข้อมูลคงที่เพื่อเก็บค่า ตัวอย่างเช่น varchar (200) จะใช้หน่วยความจำเพิ่มเติมที่ varchar (5) นี่ไม่ใช่ปัญหาพื้นที่เก็บข้อมูล แต่ยังเป็นสิ่งที่ควรพิจารณาเมื่อกำหนดคอลัมน์ของคุณ


ตัวเลขด้านบนถือว่าเป็นCHARACTER SETlatin1 หรือ ascii สำหรับ utf8 พื้นที่เก็บข้อมูลที่ต้องการCHAR(4)คือ 12
Rick James
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.