การบำรุงรักษาดัชนี MySQL


12

ฉันทำวิจัยจำนวนมากเกี่ยวกับวิธีการบำรุงรักษาดัชนีใน MySQL เพื่อป้องกันการแตกแฟรกเมนต์และเพื่อเพิ่มประสิทธิภาพการดำเนินการของแบบสอบถามบางอย่าง

ฉันคุ้นเคยกับสูตรนั้นที่คำนวณอัตราส่วนระหว่างพื้นที่ว่างสูงสุดที่มีอยู่สำหรับตาราง VS พื้นที่ที่ใช้โดยข้อมูลและดัชนี

อย่างไรก็ตามคำถามหลักของฉันยังคงไม่มีคำตอบ บางทีนี่อาจเป็นเพราะฉันคุ้นเคยกับการบำรุงรักษาดัชนีใน SQL Server และฉันมักจะคิดว่าใน MySQL มันควรจะคล้ายกัน

ในเซิร์ฟเวอร์ SQL คุณสามารถมีดัชนีได้หลายดัชนีและแต่ละดัชนีสามารถมีการแตกแฟรกเมนต์ระดับต่างกัน จากนั้นคุณสามารถเลือกและดำเนินการ 'REORGANIZE' หรือ 'REBUILD' ในดัชนีนั้นโดยไม่กระทบต่อส่วนที่เหลือ

ความรู้ของฉันอย่างดีที่สุดไม่มี 'การแตกแฟรกเมนต์ของตาราง' และ SQL Server ไม่ได้จัดเตรียมเครื่องมือใด ๆ เพื่อแก้ไข 'การแตกแฟรกเมนต์ตาราง' สิ่งที่มีให้คือเครื่องมือในการตรวจสอบการแตกแฟรกเมนต์ของดัชนี (เข้าใจเช่นอัตราส่วนระหว่างจำนวนหน้าที่ใช้โดยดัชนีเทียบกับความสมบูรณ์ของหน้าและความต่อเนื่องกัน) รวมทั้งการกระจายตัวของภายในและภายนอก

ทั้งหมดนี้ค่อนข้างตรงไปตรงมาที่จะเข้าใจอย่างน้อยก็สำหรับฉัน

ตอนนี้เมื่อถึงคราวที่ต้องรักษาดัชนีใน MySQL จะมีเพียงแนวคิดของ 'การแตกแฟรกเมนต์ของตารางดังกล่าวข้างต้น

ตารางใน MySQL สามารถมีดัชนีได้หลายดัชนี แต่เมื่อฉันตรวจสอบ 'อัตราส่วนการกระจายตัวของ' ด้วยสูตรที่มีชื่อเสียงนั้นฉันไม่เห็นการกระจายตัวของดัชนีแต่ละรายการ แต่ตารางโดยรวม

เมื่อฉันต้องการเพิ่มประสิทธิภาพดัชนีใน MySQL ฉันไม่ได้เลือกดัชนีเฉพาะเพื่อดำเนินการ (เช่นใน SQL Server) แต่ฉันทำงาน 'OPTIMIZE' ในตารางทั้งหมดซึ่งน่าจะส่งผลต่อดัชนีทั้งหมด

เมื่อตารางได้รับการปรับให้เหมาะสมใน MySQL อัตราส่วนระหว่างพื้นที่ที่ใช้โดย data + index VS จะลดพื้นที่โดยรวมซึ่งแนะนำการจัดระเบียบทางกายภาพบางประเภทในฮาร์ดไดรฟ์ใหม่ซึ่งแปลเป็นการลดพื้นที่ทางกายภาพ อย่างไรก็ตามการกระจายตัวของดัชนีไม่เพียง แต่เกี่ยวกับพื้นที่ทางกายภาพ แต่โครงสร้างของต้นไม้ที่มีการเปลี่ยนแปลงตลอดเวลาเนื่องจากการแทรกและการปรับปรุง

ในที่สุดฉันก็ได้ตารางใน InnoDB / MySQL ตารางนั้นมีระเบียน 3 ล้านระเบียน 105 คอลัมน์และดัชนี 55 รายการ มันคือ 1.5GB ไม่รวมดัชนีซึ่งเป็น 2.1GB

ตารางนั้นมีการเข้าชมหลายพันครั้งต่อวันสำหรับการอัปเดตการแทรก (เราไม่ได้ลบบันทึก)

ตารางนั้นถูกสร้างขึ้นเป็นเวลาหลายปีและฉันรู้ว่าไม่มีใครรักษาดัชนีไว้ได้

ฉันคาดหวังว่าจะพบการกระจายตัวของขนาดใหญ่ในนั้น แต่เมื่อฉันทำการคำนวณการกระจายตัวตามที่กำหนด

free_space / (data_length + index_length)

ปรากฎว่าฉันมีการกระจายตัวเพียง 0.2% IMHO ที่ค่อนข้างไม่สมจริง

ดังนั้นคำถามใหญ่คือ:

  1. ฉันจะตรวจสอบการกระจายตัวของดัชนีเฉพาะใน MySQL ได้อย่างไรไม่ใช่ตารางโดยรวม
  2. OPTIMIZE TABLE จริง ๆ แล้วแก้ไขการกระจายตัวของดัชนีภายใน / ภายนอกเช่นเดียวกับใน SQL Server หรือไม่?
  3. เมื่อฉันปรับตารางใน MySQL ให้เหมาะสมมันจริง ๆ แล้วสร้างดัชนีทั้งหมดในตารางหรือไม่
  4. เป็นจริงหรือไม่ที่จะคิดว่าการลดพื้นที่ทางกายภาพของดัชนี (โดยไม่ต้องสร้างต้นไม้ขึ้นใหม่) จะแปลเป็นประสิทธิภาพที่ดีขึ้นจริงหรือ

ตารางเพิ่มประสิทธิภาพจะล้างดัชนีกลุ่มบน Innodb อย่างแน่นอน

1
มันเป็นคำถามที่ดีไม่ใช่แค่การเขียนโปรแกรม จะถูกย้ายไปที่ที่อยู่:>

คำตอบ:


6

การแตกแฟรกเมนต์ของดัชนีถูกประเมินค่ามากเกินไป ไม่ต้องเป็นห่วงนะ.

InnoDB สองก้อนที่อยู่ติดกันและค่อนข้างว่างเปล่านั้นถูกรวมเข้าด้วยกันเป็นกระบวนการทางธรรมชาติ

การกระทำแบบสุ่มใน BTree ทำให้แรงโน้มถ่วงเคลื่อนที่ไปสู่ค่าเฉลี่ยเต็ม 69% แน่นอนว่านี่ไม่ใช่ 100% แต่ค่าโสหุ้ยของ "การแก้ไข" มันไม่คุ้มค่า

SHOW TABLE STATUS ให้ตัวชี้วัดบางอย่างแก่คุณ แต่มีข้อบกพร่อง - "Data_free" มีพื้นที่ว่าง "ว่าง" แต่ไม่ใช่ที่ว่าง "ว่าง" อื่น

มีพื้นที่ที่ไม่ได้ใช้ในแต่ละบล็อก ฟรี 16KB บล็อก ฟรี "extents" (nMB ชิ้น); แถว MVCC ที่รอการเก็บเกี่ยว โหนดที่ไม่ใช่ใบไม้มีการแยกส่วนของมันเอง เป็นต้น

Percona และ Oracle มีวิธีที่แตกต่างกันในการดูว่าดัชนีมีขนาดใหญ่เพียงใด (จำนวนบล็อก) ฉันคิดว่าทั้งคู่ไม่มีประโยชน์เพราะคำจำกัดความของ "ฟรี" ดูเหมือนว่าบล็อก (16KB แต่ละบล็อก) จะถูกจัดสรรเป็นส่วน ๆ (หลาย MB) ดังนั้นจึงนำไปสู่การเชื่อว่ามีการแตกแฟรกเมนต์ทุกประเภท ในความเป็นจริงมันเป็นเพียงหนึ่งในหลาย ๆ MB และOPTIMIZE TABLEไม่จำเป็นต้องเรียกคืนพื้นที่ใด ๆ เลย

ถ้า SQL Server ใช้ BTrees แสดงว่าไม่มี "การแตกแฟรกเมนต์" คิดว่าเกิดอะไรขึ้นกับ "การแบ่งบล็อก" หรือคิดค่าใช้จ่ายในการจัดเรียงข้อมูลอย่างต่อเนื่อง ไม่ว่าคุณจะแพ้

หมายเหตุเพิ่มเติมว่าตารางและดัชนีเป็นโครงสร้างที่เหมือนกัน:

  • B + Tree ขึ้นอยู่กับดัชนีบางส่วน
  • "ข้อมูล" ขึ้นอยู่กับคีย์หลัก; แต่ละดัชนีรองเป็นต้นไม้ B + ตามดัชนี
  • โหนดลีฟของ "data" มีคอลัมน์ทั้งหมดของตาราง
  • โหนดลีฟของดัชนีรองมีคอลัมน์ของดัชนีรองนั้นรวมทั้งคอลัมน์ของคีย์หลัก

หากคุณมีinnodb_file_per_table = ONคุณจะเห็นการหดตัว (ถ้ามี) อย่างชัดเจนหลังจากตาราง OPTIMIZE โดยดูที่.ibdขนาดของไฟล์ สำหรับOFFข้อมูลถูกฝังอยู่ในibdata1นั้น แต่SHOW TABLE STATUSอาจมีความแม่นยำพอสมควรเนื่องจากพื้นที่ "ฟรี" ทั้งหมดเป็นของทุกตาราง ดียกเว้นชิ้นที่จัดสรรไว้ล่วงหน้า

คุณอาจสังเกตเห็นว่าตาราง file-table ต่อตารางที่ได้รับการปรับปรุงใหม่อย่างสมบูรณ์มี 4M, 5M, 6M หรือ 7M ของ Data_free นี่คือการจัดสรรล่วงหน้าและความล้มเหลวในการให้รายละเอียดนาทีแก่คุณ

ฉันทำงานกับ InnoDB มานานกว่าทศวรรษแล้ว ฉันทำงานกับตารางที่แตกต่างกันหลายพันรายการทั้งใหญ่และเล็ก OPTIMIZE TABLEผมบอกว่าเพียงหนึ่งตารางในพันจริงๆต้อง การใช้บนโต๊ะอื่นเป็นของเสีย

105 คอลัมน์มีจำนวนมาก แต่อาจจะไม่มากเกินไป

คุณมี 55 ดัชนีในหนึ่งตารางหรือไม่? นั่นเป็นสิ่งที่ไม่ดี INSERTนั่นคือการปรับปรุงต่อ 55 เรามาคุยกันต่อไปว่า โปรดจำไว้ว่าINDEX(a)มันไร้ประโยชน์ถ้าคุณมีINDEX(a,b)เช่นกัน และINDEX(flag)ไร้ประโยชน์เพราะความสำคัญต่ำ (แต่INDEX(flag, foo)อาจมีประโยชน์)

Q1: ไม่มีวิธีที่ดีในการตรวจสอบการกระจายตัวของข้อมูลในทุกรูปแบบไม่ว่าจะเป็นข้อมูลหรือดัชนีรอง

ไตรมาสที่ 2 ไตรมาสที่ 3: OPTIMIZE TABLEจะสร้างตารางโดยCREATEingตารางใหม่และINSERTingแถวทั้งหมดแล้วและRENAMEing DROPpingการแทรกข้อมูลตามลำดับ PK อีกครั้งทำให้มั่นใจได้ว่าข้อมูลมีการจัดระเบียบอย่างดี ดัชนีเป็นอีกเรื่องหนึ่ง

Q4: คุณสามารถ DROPและreCREATEแต่ละดัชนีเพื่อล้างข้อมูลได้ แต่นี่เป็นกระบวนการที่ช้ามาก 5.6 มีการเพิ่มความเร็วบางอย่าง แต่ฉันไม่รู้ว่าพวกเขาช่วยในการจัดเรียงข้อมูลหรือไม่

นอกจากนี้ยังเป็นไปได้ALTER TABLE ... DISABLE KEYSแล้วENABLEพวกเขา นี่อาจเป็นการสร้างดัชนีรองทั้งหมดที่มีประสิทธิภาพยิ่งขึ้นในคราวเดียว


Rick ฉันหมายถึงฟิลด์ '105' ไม่ใช่ไฟล์
Nicolas

1

ฉันจะตรวจสอบการกระจายตัวของดัชนีเฉพาะใน MySQL ได้อย่างไรไม่ใช่ตารางโดยรวม

ผ่าน

OPTIMIZE TABLE จริง ๆ แล้วแก้ไขการกระจายตัวของดัชนีภายใน / ภายนอกเช่นเดียวกับใน SQL Server หรือไม่?

มันสร้างตารางและดัชนีอย่างสมบูรณ์

เมื่อฉันปรับตารางใน MySQL ให้เหมาะสมมันจริง ๆ แล้วสร้างดัชนีทั้งหมดในตารางหรือไม่

นั่นเป็นคำถามเดียวกันกับคำตอบเดียวกัน

เป็นจริงหรือไม่ที่จะคิดว่าการลดพื้นที่ทางกายภาพของดัชนี (โดยไม่ต้องสร้างต้นไม้ขึ้นใหม่) จะแปลเป็นประสิทธิภาพที่ดีขึ้นจริงหรือ

ไม่จริงที่จะคิดว่าคุณสามารถลดพื้นที่โดยไม่ต้องสร้างต้นไม้ขึ้นใหม่ พวกเขาไปด้วยกัน


เพื่อตอบ # 1: แม้ว่ามันจะไม่ถูกต้อง แต่SHOW TABLE STATUS LIKE 'mytable'จะให้คำแนะนำในdata freeคอลัมน์ dev.mysql.com/doc/refman/5.6/en/show-table-status.html
Jehad Keriaki

ฉันรู้ แต่ก็ยังขาดพื้นที่ของดัชนีเฉพาะ
นิโคลัส
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.