คำถามของฉันมี 2 ส่วน
- มีวิธีการระบุขนาดเริ่มต้นของฐานข้อมูลใน PostgreSQL หรือไม่?
- หากไม่มีคุณจะจัดการกับการแตกแฟรกเมนต์อย่างไรเมื่อฐานข้อมูลเติบโตขึ้นตามกาลเวลา
ฉันเพิ่งย้ายจาก MSSQL ไปยัง Postgres และหนึ่งในสิ่งที่เราทำในโลก MSSQL เมื่อสร้างฐานข้อมูลคือการระบุขนาดเริ่มต้นของฐานข้อมูลและบันทึกธุรกรรม การกระจายตัวที่ลดลงนี้และประสิทธิภาพที่เพิ่มขึ้นโดยเฉพาะอย่างยิ่งถ้าขนาด "ปกติ" ของฐานข้อมูลเป็นที่รู้จักกันล่วงหน้า
ประสิทธิภาพของฐานข้อมูลของฉันลดลงตามขนาดที่เพิ่มขึ้น ตัวอย่างเช่นปริมาณงานที่ฉันวางผ่านตามปกติใช้เวลา 10 นาที เมื่อฐานข้อมูลเติบโตขึ้นเวลานี้จะเพิ่มขึ้น การทำ VACUUM, VACUUM FULL และ VACUUM FULL ANALYZE ไม่ปรากฏขึ้นเพื่อแก้ไขปัญหา สิ่งที่แก้ปัญหาด้านประสิทธิภาพคือการหยุดฐานข้อมูลแยกส่วนไดรฟ์แล้วทำการ VACUUM FULL ANALYZE ใช้เวลาทดสอบประสิทธิภาพของฉันกลับไปเป็น 10 นาทีเดิม สิ่งนี้ทำให้ฉันสงสัยว่าการแตกออกเป็นส่วน ๆ คือสิ่งที่ทำให้ฉันเจ็บปวด
ฉันไม่สามารถค้นหาการอ้างอิงถึงการจองพื้นที่ตาราง / ฐานข้อมูลใน Postgres ได้ ฉันกำลังใช้คำศัพท์ที่ไม่ถูกต้องและไม่พบสิ่งใดเลยหรือมีวิธีอื่นในการลดการแตกแฟรกเมนต์ของระบบไฟล์ใน Postgres
ตัวชี้ใด ๆ
การแก้ไขปัญหา
คำตอบที่ให้มาช่วยยืนยันสิ่งที่ฉันเริ่มสงสัย PostgreSQL จัดเก็บฐานข้อมูลข้ามหลายไฟล์และนี่คือสิ่งที่ช่วยให้ฐานข้อมูลเติบโตโดยไม่ต้องกังวลเรื่องการแตกแฟรกเมนต์ พฤติกรรมเริ่มต้นคือการแพ็คไฟล์เหล่านี้ไปที่ขอบด้วยข้อมูลตารางซึ่งเป็นสิ่งที่ดีสำหรับตารางที่ไม่ค่อยเปลี่ยนแปลง แต่ไม่ดีสำหรับตารางที่มีการปรับปรุงบ่อยครั้ง
PostgreSQL ใช้MVCCเพื่อจัดเตรียมการเข้าถึงข้อมูลตารางพร้อมกัน ภายใต้ชุดรูปแบบนี้การอัปเดตแต่ละครั้งจะสร้างเวอร์ชันใหม่ของแถวที่อัปเดต (ซึ่งอาจผ่านการประทับเวลาหรือหมายเลขเวอร์ชันใครจะรู้) ข้อมูลเก่าจะไม่ถูกลบทันที แต่ทำเครื่องหมายเพื่อลบ การลบที่แท้จริงเกิดขึ้นเมื่อมีการดำเนินการ VACUUM
สิ่งนี้เกี่ยวข้องกับปัจจัยเติมอย่างไร ปัจจัยการเติมเริ่มต้นของตารางเต็ม 100 เต็มหน้าตารางซึ่งหมายความว่าไม่มีพื้นที่ภายในหน้าตารางที่จะถือแถวที่ปรับปรุงเช่นแถวที่ปรับปรุงจะถูกวางในหน้าตารางที่แตกต่างจากแถวเดิม สิ่งนี้ไม่ดีสำหรับการแสดงตามประสบการณ์ของฉัน เนื่องจากตารางสรุปของฉันได้รับการอัปเดตบ่อยมาก (มากถึง 1,500 แถว / วินาที) ฉันเลือกที่จะตั้งค่าตัวประกอบการเติมเท่ากับ 20 นั่นคือ 20% ของตารางจะเป็นข้อมูลแถวที่แทรกและ 80% สำหรับข้อมูลการอัปเดต แม้ว่าสิ่งนี้อาจดูมากเกินไปพื้นที่จำนวนมากที่สงวนไว้สำหรับแถวที่อัพเดตหมายความว่าแถวที่อัปเดตจะอยู่ภายในหน้าเดียวกับต้นฉบับและมีหน้าตารางไม่เต็มตามเวลาที่ autovacuum daemon ทำงานเพื่อลบแถวที่ล้าสมัย
หากต้องการ "แก้ไข" ฐานข้อมูลของฉันฉันได้ทำสิ่งต่อไปนี้
- ตั้งค่าตัวประกอบการเติมของตารางสรุปของฉันเป็น 20 คุณสามารถทำได้เมื่อสร้างโดยส่งพารามิเตอร์ไปที่CREATE TABLEหรือหลังจากความจริงผ่าน ALTER TABLE ฉันออกคำสั่ง plpgsql ต่อไปนี้:
ALTER TABLE "my_summary_table" SET (fillfactor = 20);
- ออกสูญญากาศเต็มรูปแบบเช่นนี้เขียนรุ่นใหม่ที่สมบูรณ์แบบของไฟล์ตารางและทำให้โดยปริยายเขียนไฟล์ตารางใหม่ที่มีปัจจัยเติมใหม่
ทำการทดสอบของฉันอีกครั้งฉันไม่เห็นประสิทธิภาพการทำงานลดลงแม้ว่าฐานข้อมูลจะมีขนาดใหญ่เท่าที่ฉันต้องการเพื่อให้มีแถวหลายล้านแถว
TL; DR - การแตกแฟรกเมนต์ของไฟล์ไม่ใช่สาเหตุ แต่เป็นการกระจายตัวของพื้นที่ตาราง นี่คือการลดลงโดยการปรับแต่งปัจจัยการเติมตารางเพื่อให้เหมาะกับกรณีการใช้งานของคุณโดยเฉพาะ