จำกัด การทำซ้ำสำหรับการดูการรีเฟรชที่สมบูรณ์แบบสมบูรณ์หรือเทียบเท่าแบบแมนนวล


10

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

มีวิธีที่จะทำให้การจำลองแบบนี้เป็นเรื่องเกี่ยวกับการสร้างซ้ำได้หรือไม่? MERGE ตามด้วย DELETE ต้องการเคียวรีซอร์สสองครั้ง มันจะคุ้มค่าหรือไม่ที่จะรวบรวมข้อมูลจำนวนมากเพื่อทำการรวมเป็นกลุ่มและลบ? มีวิธีที่ดีกว่า?

ปรับปรุง:

ฉันสำรวจโดยใช้ตารางชั่วคราวทั่วโลกเป็นพื้นที่จัดเตรียม แม้ว่าจะใช้การทำซ้ำน้อยกว่าครึ่ง แต่พวกเขายังคงใช้งานได้มาก


คุณสามารถโพสต์รหัส gtt ได้ไหม? gtt ไม่สร้างการทำซ้ำโดยตรง แต่จะสร้างเลิกทำ - และเลิกสร้างการทำซ้ำ insertops สร้างการเลิกทำน้อยกว่าdeleteหรือupdateops มาก (แทบจะไม่มีเลย) การมีหลาย gtts เพื่อหลีกเลี่ยง ops แพง ๆ อาจเป็นวิธีที่ดี
Jack says ลอง topanswers.xyz

@Jack Douglas psoug.org/reference/gtt.htmlมีการสาธิต GTT Redo Generation สาธิตการลดการทำซ้ำ 60% ระหว่างตารางจริงและ GTT for inserts สิ่งนี้ตรงกับผลลัพธ์ที่ฉันเห็นและดีกว่า แต่ไม่ดีเท่าที่ฉันต้องการ
Leigh Riffel

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

คำตอบ:


5

นี่เป็นเพียงเพื่อแสดงให้เห็นถึงการใช้งานซ้ำของinsertการดำเนินการต่างๆมากกว่าที่จะตอบคำถามทั้งหมด ผลลัพธ์ในอินสแตนซ์ 10g ของฉันไม่ได้กำหนด 100% แต่ภาพกว้างยังคงเหมือนเดิมทุกครั้งที่ฉันวิ่งผ่าน

สำหรับตารางฮีปฉันไม่ทราบว่าเพราะเหตุใดจึงinsert /*+ append */สร้างการทำซ้ำเพิ่มเติม

testbed:

create table heap_noappend(id integer, dummy char(500));
create table heap_append(id integer, dummy char(500));
create global temporary table gtt_noappend(id integer, dummy char(500));
create global temporary table gtt_append(id integer, dummy char(500));
create global temporary table gtt_results(stage integer, val integer);

ทดสอบ:

insert into gtt_results(stage, val)
select 0, value from v$statname join v$sesstat using(statistic#)
where sid=sys_context('userenv','sid') and name='redo size';

insert into heap_noappend(id, dummy)
select level, 'A' from dual connect by level<1000;

insert into gtt_results(stage, val)
select 1, value from v$statname join v$sesstat using(statistic#)
where sid=sys_context('userenv','sid') and name='redo size';

insert /*+ append */ into heap_append(id, dummy)
select level, 'A' from dual connect by level<1000;

insert into gtt_results(stage, val)
select 2, value from v$statname join v$sesstat using(statistic#)
where sid=sys_context('userenv','sid') and name='redo size';

insert into gtt_noappend(id, dummy)
select level, 'A' from dual connect by level<1000;

insert into gtt_results(stage, val)
select 3, value from v$statname join v$sesstat using(statistic#)
where sid=sys_context('userenv','sid') and name='redo size';

insert /*+ append */ into gtt_append(id, dummy)
select level, 'A' from dual connect by level<1000;

insert into gtt_results(stage, val)
select 4, value from v$statname join v$sesstat using(statistic#)
where sid=sys_context('userenv','sid') and name='redo size';

ผลลัพธ์:

select * 
from( select decode(stage,1,'heap noappend',
                          2,'heap append',
                          3,'gtt noappend',
                          4,'gtt append') as operation, 
             val-lag(val) over(order by stage) as redo 
      from gtt_results)
where redo is not null;

OPERATION     REDO                   
------------- ---------------------- 
heap noappend 606932                 
heap append   690768                 
gtt noappend  41488                  
gtt append    256                   

คุณถูกต้องแน่นอน. ฉันควรจะได้ว่าในการทดสอบของพวกเขา ฉันจะลองดู
Leigh Riffel

6

คำถามที่ดี. ฉัน "แก้ไข" ปัญหานี้สำหรับสถานการณ์ของฉันในขณะที่กลับโดยการทำ MV และดัชนีใด ๆ ที่พวกเขา NOLOGGING สถานการณ์ของฉันไม่มีประเด็น - ฉันกำลังทำมุมมองใหม่อย่างเต็มรูปแบบแล้วทำไมฉันต้องทำซ้ำ


1
คุณอาจต้องการ ATOMIC_REFRESH = falseด้วย (ใน 10g ขึ้นไป) ไม่แน่ใจว่าสิ่งใดที่เกี่ยวข้องกับฐานข้อมูลสแตนด์บายหรือการกู้คืนด้วยบันทึกการจัดเก็บ
แจ็คบอกว่าลอง topanswers.xyz

ฉันรันโลจิคัลและสแตนด์บายแบบฟิสิคัลบนฐานข้อมูลที่ฉันทำด้วย ไม่มีปัญหา ฉันพบปัญหาในการทำสำเนา DB - ต้องดูบันทึกย่อของฉัน แต่มีข้อผิดพลาดบางครั้งฉันจะได้รับเกี่ยวกับการกู้คืนข้อมูลบนพื้นที่ตารางที่มีตาราง nologging ฉันได้อ่านคำแนะนำเพื่อสร้าง tablespace ที่สงวนไว้สำหรับตาราง / ดัชนีที่ไม่ใช่การล็อกเพื่อหลีกเลี่ยงปัญหาดังกล่าว ฉันคิดออกว่าจะแก้มันอย่างไร
DCookie

@ แจ็คฉันเชื่อว่าฉันต้องใช้การรีเฟรชที่ไม่ใช่อะตอม
DCookie

อืมถ้าฉันใช้มุมมองแบบร่างที่เป็นมาตรฐานมันต้องทำการรีเฟรชอะตอมดังนั้นสิ่งนี้จะไม่ได้ผลสำหรับฉัน บุคคลอื่นอาจพบว่ามีประโยชน์ดังนั้นจึงเป็นคำตอบที่ดี
Leigh Riffel

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