สมมติฐาน
เนื่องจากไม่มีข้อมูลใน Q ฉันจะถือว่า:
- ข้อมูลของคุณมาจากไฟล์บนเซิร์ฟเวอร์ฐานข้อมูล
- ข้อมูลจะถูกจัดรูปแบบเหมือนกับ
COPY
เอาต์พุตโดยมีค่าเฉพาะ id
สำหรับแต่ละแถวเพื่อจับคู่กับตารางเป้าหมาย
ถ้าไม่ให้ฟอร์แมตอย่างถูกต้องก่อนหรือใช้COPY
ตัวเลือกเพื่อจัดการกับรูปแบบ
- คุณกำลังอัปเดตทุกแถวในตารางเป้าหมายหรือส่วนใหญ่
- คุณสามารถที่จะวางและสร้างตารางเป้าหมายใหม่ได้
นั่นหมายความว่าไม่มีการเข้าถึงพร้อมกัน ลองพิจารณาคำตอบที่เกี่ยวข้องนี้:
- ไม่มีวัตถุใด ๆ เลยยกเว้นดัชนี
วิธีการแก้
ผมขอแนะนำให้คุณไปด้วยวิธีการที่คล้ายกันตามที่ระบุไว้ในการเชื่อมโยงจากกระสุนที่สามของคุณ ด้วยการเพิ่มประสิทธิภาพที่สำคัญ
หากต้องการสร้างตารางชั่วคราวมีวิธีที่ง่ายกว่าและเร็วกว่า:
CREATE TEMP TABLE tmp_tbl AS SELECT * FROM tbl LIMIT 0;
ขนาดใหญ่เพียงครั้งเดียวUPDATE
จากตารางชั่วคราวภายในฐานข้อมูลจะเร็วกว่าการอัปเดตส่วนบุคคลจากนอกฐานข้อมูลด้วยคำสั่งที่หลากหลาย
ในรูปแบบของ PostgreSQL MVCCเป็นUPDATE
วิธีการที่จะสร้างรุ่นแถวใหม่และทำเครื่องหมายเดิมเป็นลบ นั่นเป็นเรื่องเกี่ยวกับราคาแพงINSERT
และDELETE
รวมกัน นอกจากนี้ยังปล่อยให้คุณมี tuples ที่ตายแล้วจำนวนมาก เนื่องจากคุณกำลังอัปเดตตารางทั้งหมดมันจะเร็วขึ้นโดยรวมในการสร้างตารางใหม่และวางตารางเก่า
หากคุณมี RAM เพียงพอให้ตั้งค่าtemp_buffers
(สำหรับเซสชันนี้เท่านั้น) สูงพอที่จะเก็บตาราง temp ใน RAM - ก่อนที่คุณจะทำสิ่งอื่น
ในการรับค่าประมาณจำนวน RAM ที่ต้องการให้รันการทดสอบด้วยตัวอย่างขนาดเล็กและใช้ฟังก์ชันขนาดวัตถุ db :
SELECT pg_size_pretty(pg_relation_size('tmp_tbl')); -- complete size of table
SELECT pg_column_size(t) FROM tmp_tbl t LIMIT 10; -- size of sample rows
สคริปต์ที่สมบูรณ์
SET temp_buffers = '1GB'; -- example value
CREATE TEMP TABLE tmp_tbl AS SELECT * FROM tbl LIMIT 0;
COPY tmp_tbl FROM '/absolute/path/to/file';
CREATE TABLE tbl_new AS
SELECT t.col1, t.col2, u.field1, u.field2
FROM tbl t
JOIN tmp_tbl u USING (id);
-- Create indexes like in original table
ALTER TABLE tbl_new ADD PRIMARY KEY ...;
CREATE INDEX ... ON tbl_new (...);
CREATE INDEX ... ON tbl_new (...);
-- exclusive lock on tbl for a very brief time window!
DROP TABLE tbl;
ALTER TABLE tbl_new RENAME TO tbl;
DROP TABLE tmp_tbl; -- will also be dropped at end of session automatically
โหลดพร้อมกัน
การดำเนินการที่เกิดขึ้นพร้อมกันบนโต๊ะ (ซึ่งฉันได้ตัดออกในข้อสันนิษฐานในตอนเริ่มต้น) จะรอเมื่อตารางถูกล็อคใกล้ถึงจุดสิ้นสุดและล้มเหลวทันทีที่มีการทำธุรกรรมเนื่องจากมีการแก้ไขชื่อตารางเป็น OID ทันที ตารางใหม่มี OID ที่แตกต่างกัน ตารางยังคงอยู่ แต่การดำเนินการที่เกิดขึ้นพร้อมกันอาจได้รับการยกเว้นและต้องทำซ้ำ รายละเอียดในคำตอบที่เกี่ยวข้องนี้:
อัปเดตเส้นทาง
หากคุณ (ต้อง) ไปที่UPDATE
เส้นทางให้ดร็อปดัชนีใด ๆ ที่ไม่จำเป็นในระหว่างการอัพเดตและสร้างใหม่ในภายหลัง มันถูกกว่ามากในการสร้างดัชนีในชิ้นเดียวกว่าที่จะอัปเดตสำหรับทุกแถว สิ่งนี้อาจอนุญาตสำหรับการปรับปรุงที่น่าสนใจ
ผมอธิบายไว้เป็นขั้นตอนที่คล้ายกันโดยใช้UPDATE
ในคำตอบที่เกี่ยวข้องอย่างใกล้ชิดเกี่ยวกับเรื่องนี้ดังนั้น