มีความแตกต่างของประสิทธิภาพใน MySQL ระหว่างขนาด varchar หรือไม่ ยกตัวอย่างเช่นและvarchar(25)
varchar(64000)
ถ้าไม่มีมีเหตุผลที่จะไม่ประกาศ varchars ทั้งหมดที่มีขนาดสูงสุดเพียงเพื่อให้แน่ใจว่าคุณไม่ได้ออกจากห้อง?
มีความแตกต่างของประสิทธิภาพใน MySQL ระหว่างขนาด varchar หรือไม่ ยกตัวอย่างเช่นและvarchar(25)
varchar(64000)
ถ้าไม่มีมีเหตุผลที่จะไม่ประกาศ varchars ทั้งหมดที่มีขนาดสูงสุดเพียงเพื่อให้แน่ใจว่าคุณไม่ได้ออกจากห้อง?
คำตอบ:
คุณต้องตระหนักถึงข้อเสียของการใช้ CHAR กับ VARCHAR
ด้วยฟิลด์ CHAR สิ่งที่คุณจัดสรรคือสิ่งที่คุณได้รับ ตัวอย่างเช่น CHAR (15) จัดสรรและจัดเก็บ 15 ไบต์ไม่ว่าคุณจะใส่อักขระในฟิลด์อย่างไร การจัดการสตริงนั้นง่ายและตรงไปตรงมาเนื่องจากขนาดของเขตข้อมูลสามารถคาดเดาได้ทั้งหมด
ด้วยฟิลด์ VARCHAR คุณจะได้รับเรื่องราวที่แตกต่างอย่างสิ้นเชิง ตัวอย่างเช่น VARCHAR (15) จะจัดสรรข้อมูลแบบไดนามิกมากถึง 16 ไบต์สูงสุด 15 สำหรับข้อมูลและอย่างน้อย 1 ไบต์เพิ่มเติมเพื่อจัดเก็บความยาวของข้อมูล หากคุณมีสตริง 'hello' ในการจัดเก็บที่ใช้เวลา 6 ไบต์ไม่ใช่ 5 การจัดการสตริงต้องดำเนินการตรวจสอบความยาวบางรูปแบบในทุกกรณี
การแลกเปลี่ยนนั้นชัดเจนมากขึ้นเมื่อคุณทำสองสิ่ง:
1. จัดเก็บล้านหรือหลายพันล้านแถว
2. การทำดัชนีคอลัมน์ที่มีทั้งแบบ CHAR หรือ VARCHAR
เห็นได้ชัดว่า VARCHAR มีความได้เปรียบเนื่องจากข้อมูลที่มีความยาวผันแปรจะสร้างแถวที่เล็กกว่าและดังนั้นจึงมีขนาดเล็กลง
เนื่องจากเขตข้อมูล CHAR ต้องการการจัดการสตริงน้อยกว่าเนื่องจากความกว้างของเขตข้อมูลคงที่การค้นหาดัชนีเทียบกับเขตข้อมูล CHAR จะเร็วกว่าค่าเฉลี่ย 20% ของเขตข้อมูล VARCHAR นี่ไม่ใช่การคาดเดาใด ๆ ในส่วนของฉัน หนังสือการออกแบบและปรับแต่งฐานข้อมูล MySQLทำสิ่งที่ยอดเยี่ยมในตาราง MyISAM เพื่อพิสูจน์สิ่งนี้ ตัวอย่างในหนังสือทำสิ่งต่อไปนี้:
ALTER TABLE tblname ROW_FORMAT=FIXED;
กองกำลังสั่งนี้เป็น VARCHARs ที่จะทำตัวเป็น CHARs ฉันทำสิ่งนี้ที่งานก่อนหน้าของฉันในปี 2550 และเอาตาราง 300GB และเร่งการค้นหาดัชนีขึ้น 20% โดยไม่เปลี่ยนแปลงอะไรเลย มันทำงานตามที่เผยแพร่ อย่างไรก็ตามมันสร้างตารางเกือบสองเท่าในขนาด แต่มันกลับไปที่การแลกเปลี่ยน # 1
คุณสามารถวิเคราะห์ข้อมูลที่เก็บไว้เพื่อดูสิ่งที่ MySQL แนะนำสำหรับการกำหนดคอลัมน์ เพียงเรียกใช้สิ่งต่อไปนี้กับตารางใด ๆ :
SELECT * FROM tblname PROCEDURE ANALYSE();
สิ่งนี้จะสำรวจตารางทั้งหมดและแนะนำคำจำกัดความคอลัมน์สำหรับทุกคอลัมน์โดยยึดตามข้อมูลที่มีค่าฟิลด์ขั้นต่ำค่าฟิลด์สูงสุดและอื่น ๆ บางครั้งคุณต้องใช้สามัญสำนึกกับการวางแผน CHAR กับ VARCHAR นี่เป็นตัวอย่างที่ดี:
หากคุณกำลังจัดเก็บที่อยู่ IP มาสก์สำหรับคอลัมน์ดังกล่าวมีความยาวสูงสุด 15 อักขระ (xxx.xxx.xxx.xxx) ฉันจะกระโดดขวาที่ CHAR (15) ใน heartbeat เนื่องจากความยาวของที่อยู่ IP จะไม่แตกต่างกันมากและความซับซ้อนที่เพิ่มขึ้นของการจัดการสตริงที่ควบคุมโดยไบต์เพิ่มเติม คุณยังสามารถทำ ANALYZE () กับคอลัมน์ดังกล่าวได้ มันอาจแนะนำ VARCHAR ด้วยซ้ำ เงินของฉันจะยังคงเป็น CHAR มากกว่า VARCHAR ในกรณีนี้
ปัญหา CHAR vs VARCHAR สามารถแก้ไขได้ผ่านการวางแผนที่เหมาะสมเท่านั้น ด้วยพลังอันยิ่งใหญ่มาพร้อมความรับผิดชอบที่ยอดเยี่ยม (ถ้อยคำที่เบื่อหู แต่จริง)
คำตอบนี้ค่อนข้างซับซ้อนจริง ๆ รุ่นสั้น: มีความแตกต่าง
เมื่อสร้างตารางชั่วคราวเพื่อกรองผลลัพธ์ (เช่นGROUP BY
คำสั่ง) ความยาวเต็มจะถูกจัดสรร
โปรโตคอลลวด (ส่งแถวไปยังลูกค้า) มีแนวโน้มที่จะจัดสรรความยาวขนาดใหญ่
เอ็นจิ้นการจัดเก็บอาจ / อาจไม่ใช้ varchar
สำหรับ (2) ฉันยอมรับว่า wire protocol ไม่ใช่สิ่งที่ฉันคุ้นเคยอย่างใกล้ชิด แต่คำแนะนำทั่วไปที่นี่คือการลองและใช้ความพยายามอย่างน้อยที่สุดเพื่อคาดเดาความยาว
คำตอบส่วนใหญ่ในหัวข้อนี้มีอายุ 5 ปีซึ่งถูกเขียนก่อน InnoDB และ utf8 เป็นค่าเริ่มต้น ขอผมเริ่มใหม่ ...
เมื่อแบบสอบถามต้องการตารางชั่วคราวภายในจะพยายามใช้MEMORY
ตาราง แต่ไม่สามารถใช้ MEMORY ได้
TEXT
/ คอลัมน์เป็นความจริงไม่ได้BLOB
TINYTEXT
VARCHAR
ใหญ่กว่าจำนวนเล็กน้อยอาจเป็น 512 ในเวอร์ชันปัจจุบันนอกจากนี้ทราบว่าจะกลายเป็นVARCHARs
CHARs
ดังนั้นVARCHAR(255)
ด้วยการCHARACTER SET utf8
ขยายเป็น 765 ไบต์โดยไม่คำนึงถึงสิ่งที่อยู่ในคอลัมน์ จากนั้นสิ่งนี้อาจถูกเรียกใช้:
MEMORY
ตารางมีขนาดใหญ่กว่าmax_heap_table_size
หรือ tmp_table_size
จะถูกแปลงเป็น MyISAM และอาจกระจายไปยังดิสก์ดังนั้นVARCHAR(25)
มีแนวโน้มที่จะอยู่MEMORY
จึงจะเร็วขึ้น (255)
ไม่ดีและ(64000)
ไม่ดี
(ในอนาคตตารางชั่วคราวอาจจะเป็นInnoDB
และส่วนหนึ่งของคำตอบนี้จะต้องแก้ไข)
คอลัมน์ varchar ที่มีขนาดทำให้ข้อความค้นหาบนทั้งตารางมีแนวโน้มที่จะใช้ตารางชั่วคราวมากขึ้น ตามหนังสือ MySQL ประสิทธิภาพสูง เมื่อเครื่องมือเพิ่มประสิทธิภาพพยายามที่จะดูว่ามันสามารถเรียกใช้แบบสอบถามนี้ในหน่วยความจำหรือถ้ามันต้องการตารางชั่วคราวมันจะดูขนาดของแถวตามคำจำกัดความของตารางหมายถึงความเร็วจะไม่พยายามดูว่าตัวอักษร 64K มีเท่าใด คุณกำลังใช้งานจริง นี่คือเหตุผลที่ผู้เขียนแนะนำให้คุณไม่ขยายวิธีการกำหนดเกินกว่าค่าที่เป็นไปได้จริงที่จะไปในคอลัมน์ เห็นได้ชัดว่าถ้าคุณตั้งค่าสำหรับแบบสอบถามเพิ่มเติมที่จะเข้าไปในตาราง temp (แม้ว่าขนาดของข้อมูลที่แท้จริงจะพอดีกับ RAM) ตอนนี้คุณมีบทลงโทษ I / O ที่คุณสามารถหลีกเลี่ยงได้
ฉันเข้าใจว่าเขตข้อมูลขนาดเล็กอาจรวมอยู่ในดัชนีโดยตรงในขณะที่ฟิลด์ที่ยาวกว่าไม่สามารถทำได้ เนื่องจากข้อ จำกัด นั้นหากคุณต้องการให้สายอักขระนั้นสามารถทำดัชนีได้ฉันจะบอกว่าให้สั้นลง ไม่เช่นนั้นการเป็นทั้งวาร์ชาทั้งสองนั้นจะเหมือนกับการเรียงลำดับหรือการเปรียบเทียบจะทำงานในเวลาเดียวกันไม่ว่าจะเป็นเขตข้อมูล 25 หรือสูงสุด
ให้แน่ใจว่าคุณไม่ได้ออกจากห้อง
วลีนี้บอกเป็นนัยว่าคุณถามคำถามเพราะคุณไม่แน่ใจเกี่ยวกับข้อมูลที่คุณจะเก็บไว้ในฐานข้อมูล หากเป็นเรื่องจริงคุณจะได้รับการบริการอย่างดีเพื่อค้นหาโดยเร็วที่สุดเท่าที่จะทำได้เพราะคุณจะต้องใช้การวางแผนกำลังการผลิต หากคุณอาจได้รับองค์ประกอบข้อมูลที่มีอักขระ 7000 ตัวคุณจำเป็นต้องรู้เพราะจะมีผลกระทบต่อประสิทธิภาพใน DBMS ใด ๆ
ที่กล่าวว่าฉันชอบที่จะมีขนาดคอลัมน์ที่เกี่ยวข้องกับเนื้อหาที่คาดหวัง ตัวอย่างเช่นหมายเลขโทรศัพท์ไม่น่าจะมีความยาวเกิน 50 ตัวอักษรแม้ว่าคุณจะใส่รหัสประเทศและนามสกุล ในทำนองเดียวกันรหัสไปรษณีย์หรือรหัสไปรษณีย์มักจะมีความยาวไม่เกิน 20 ตัวอักษร