การอัพเดต 700 ล้านแถวเป็นค่าเดียวกัน


12

ฉันมีคลังข้อมูล (oracle) ที่ฉันต้องตั้งค่าคอลัมน์เป็นค่าเดียวกันสำหรับทั้ง 700 ล้านแถว

ฉันไม่มีสิทธิ์การเข้าถึงระดับผู้ดูแลระบบหรือการเข้าถึงผู้ดูแลระบบดังนั้นจึงจำเป็นต้องทำให้สำเร็จด้วย sql พื้นฐานและไม่มีตาราง temp ที่สร้างขึ้น

สิ่งที่ซับซ้อนกว่านั้นคือถ้าฉันพยายามทำการอัพเดทง่ายๆโดยที่ 1 = 1 มันจะหมดพื้นที่ทำซ้ำ

วิธีที่ฉันให้มันทำงานตอนนี้วนซ้ำเช่นนี้:

loop
  update mytable set mycolumn = '1' where mycolumn is null and rownum < 50000;
  commit;
end loop

แต่ฉันรู้ว่านี่อาจไร้เดียงสาและต้องมีวิธีแก้ปัญหาที่รวดเร็วและสง่างามกว่า


แบ่งพาร์ติชันเป็นตารางหรือไม่?
แจ็คบอกว่าลอง topanswers.xyz

ฉันไม่เชื่ออย่างนั้น มีดัชนีอยู่สองสามตัว แต่ไม่มีดัชนีใดที่เกี่ยวข้องกับคอลัมน์ที่ฉันกำลังอัปเดต
หนี้

คำตอบ:


4

หากคุณมีพื้นที่ที่คุณสามารถCTAS ใช้น้อยที่สุดยกเลิก หากคุณมีดัชนีใด ๆ การทำด้วยวิธีอื่นจะช้ามากและสร้างการบันทึกอย่างบ้าคลั่ง

ในกรณีที่คุณมี IOT เดียวโดยไม่มีดัชนีรองใด ๆ หรือคลัสเตอร์ตารางเดียวคุณสามารถก้าวผ่านคีย์หลัก / คลัสเตอร์ที่อัปเดตเป็นชิ้น ๆ โดยไม่ต้องสแกนตารางทั้งหมดอีกครั้งเพื่อค้นหาฟิลด์ที่ยังไม่ได้อัปเดต

--edit

ฉันไม่สามารถสร้างตารางรองได้ ... มีดัชนีอยู่สองสามอัน แต่ไม่มีดัชนีใดที่เกี่ยวข้องกับคอลัมน์ที่ฉันกำลังอัปเดต

จากนั้นฉันขอแนะนำให้แบ่งตารางออกเป็นส่วน ๆ สำหรับการประมวลผลโดยใช้สิ่งที่คุณกำลังทำดัชนีอยู่ (แม้ว่าจะเป็นคอลัมน์เดียวคุณสามารถแบ่งออกเป็นช่วงของค่า) ซึ่งจะทำ FTS หนึ่งครั้งแทนที่จะเป็นหนึ่งชิ้นสำหรับแต่ละชิ้น รหัส. คุณจะต้องอยู่กับการทำซ้ำจำนวนมากอันน่ากลัวและจะลบล้างพื้นที่การเลิกทำของคุณด้วย (ดังนั้นจึงไม่ย้อนหลัง)

--edit2

หากคุณสามารถเพิ่ม / เปลี่ยนชื่อ / วางคอลัมน์คุณสามารถทำได้อย่างมีประสิทธิภาพมากแต่ใช้เพียง 11g


1
หาก DBA ของคุณให้คุณทำNOLOGGINGซึ่งจะทำให้ hotstandbys ใช้ไม่ได้
ออกุสตุส

แน่นอนและการสำรองข้อมูลในภายหลังจะเป็นความคิดที่ดีเช่นกัน - แต่นี่เป็นคลังสินค้าและnologgingเป็นเครื่องมือสำหรับคลังสินค้า
แจ็คบอกว่าลอง topanswers.xyz

ฉันไม่สามารถสร้างตารางรองได้แน่นอนไม่ใหญ่เท่าตารางแรกแม้ว่าจะเป็นเพียงชั่วคราวก็ตาม
owook

ลิงก์ 11g ของคุณดูสดใส แต่ฉันเห็นความคิดเห็นที่นั่นสำหรับตาราง 60 ม. มันยังคงช้าอย่างน่ากลัวเพราะต้องกำหนดค่าสำหรับทุกแถว เนื่องจากตารางของฉันมีขนาด 10 เท่าวิธีการนั้นอาจไม่ได้รับการปรับปรุง
owook

@owook ไม่มีใน 11g การดำเนินการนี้มีความรวดเร็วและไม่ได้กำหนดค่าสำหรับทุกแถว"สำหรับบางชนิดของตาราง (เช่นตารางโดยไม่ต้องคอลัมน์ LOB)" ลองใช้ชุดย่อยของตาราง ( create table foo as select * from bar where rownum<100000)
แจ็คบอกลอง topanswers.xyz

1

หากคุณใช้ 11g ให้วางคอลัมน์แล้วเพิ่มกลับเป็นคอลัมน์ NOT NULL ด้วยค่าเริ่มต้น สิ่งนี้ตอบโต้ได้ง่าย แต่ Oracle จะเก็บค่าเริ่มต้นไว้ในคำจำกัดความของตารางแทนค่าเริ่มต้น ณ เวลารันไทม์

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