วิธีที่มีประสิทธิภาพที่สุดในการเพิ่มคอลัมน์อนุกรมลงในตารางขนาดใหญ่


10

อะไรที่เร็วที่สุดวิธีการเพิ่มคอลัมน์ BIGSERIAL ไปยังตารางขนาดใหญ่ (~ 3 Bil. แถว ~ 174Gb)?

แก้ไข:

  • ฉันต้องการให้คอลัมน์เป็นค่าที่เพิ่มขึ้นสำหรับแถวที่มีอยู่ ( NOT NULL)
  • ฉันไม่ได้ตั้งสารเติม (ซึ่งดูเหมือนว่าจะเป็นการตัดสินใจที่ไม่ดีในการหวนกลับ)
  • ฉันไม่มีปัญหาเกี่ยวกับพื้นที่ดิสก์เพียงต้องการให้เร็วที่สุดเท่าที่จะเป็นไปได้

คำตอบ:


12

มีอะไรผิดปกติกับ:

ALTER TABLE foo ADD column bar bigserial;

จะเต็มไปด้วยค่าที่ไม่ซ้ำกันโดยอัตโนมัติ (เริ่มต้นด้วย 1)

หากคุณต้องการจำนวนแถวที่มีอยู่ทุกที่แถวในตารางทุกต้องมีการปรับปรุง หรือไม่

ตารางจะถูกขยายขนาดเป็นสองเท่าของขนาดหากไม่สามารถใช้ tuples ที่ตายแล้วหรือพื้นที่ว่างบนหน้าข้อมูล ประสิทธิภาพของการดำเนินการอาจได้รับประโยชน์มากมายจากการที่FILLFACTORต่ำกว่า 100 หรือเพียงแค่ tuples ตายแบบสุ่มที่แผ่กระจายไปทั่วโต๊ะ มิฉะนั้นคุณอาจต้องการเรียกใช้VACUUM FULL ANALYZEหลังจากนั้นเพื่อกู้คืนพื้นที่ว่างในดิสก์ แม้ว่ามันจะไม่รวดเร็ว

pgstattuple
คุณอาจสนใจในส่วนขยายนี้ มันช่วยให้คุณรวบรวมสถิติในตารางของคุณ หากต้องการค้นหา tuples ที่ตายแล้วและพื้นที่ว่าง:

ติดตั้งส่วนขยายหนึ่งครั้งต่อดาต้าเบส:

CREATE EXTENSION pgstattuple;

โทร:

SELECT * FROM pgstattuple('tbl');

ทางเลือก

หากคุณสามารถที่จะสร้างตารางใหม่ซึ่งจะแบ่งมุมมองขึ้นอยู่กับกุญแจต่างประเทศ ...

สร้างสำเนาที่ว่างเปล่าของตารางเก่า:

CREATE new_tbl AS
SELECT *
FROM   old_tbl
LIMIT  0;

เพิ่มคอลัมน์ bigserial:

ALTER new_tbl ADD column bar bigserial;

ข้อมูล INSERT จากตารางเก่าเติม bigserial โดยอัตโนมัติ:

INSERT INTO new_tbl
SELECT *    --  new column will be filled with default
FROM   old_tbl
ORDER  BY something; -- or don't order if you don't care: faster

คอลัมน์ bigserial ใหม่จะหายไปในการเลือกของ INSERT และจะเต็มไปด้วยค่าเริ่มต้นโดยอัตโนมัติ คุณสามารถสะกดคอลัมน์ทั้งหมดและเพิ่มลงnextval()ในSELECTรายการในลักษณะพิเศษเดียวกัน

ตรวจสอบให้แน่ใจว่าคุณได้รับข้อมูลทั้งหมดในตารางใหม่
ดัชนีเพิ่มข้อ จำกัด ทริกเกอร์ที่คุณมีในตารางเก่าตอนนี้

DROP TABLE old_tbl;
ALTER TABLE new_tbl RENAME TO old_tbl;

อาจจะค่อนข้างเร็วโดยรวมเลยทีเดียว สิ่งนี้ทำให้คุณมีตารางวานิลลา (และดัชนี) โดยไม่มีการขยายตัวใด ๆ

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


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