Узнать, когда таблица была обновлена ​​в Oracle без полного сканирования

Я создаю коннектор Oracle, который периодически считывает данные из пары очень больших таблиц, некоторые из которых разделены на разделы.

Я пытаюсь выяснить, какие таблицы были обновлены с момента последнего чтения, чтобы избежать ненужных запросов. У меня есть последний ora_rowscn или updated_at, и единственные методы, которые я нахожу, требуют полного сканирования таблицы, чтобы увидеть, есть ли в таблице новые или обновленные строки.

Есть ли способ узнать, была ли вставлена ​​или обновлена ​​строка таблицы без полного сканирования?


person Ido Peretz    schedule 17.12.2018    source источник
comment
У вас есть индекс updated_at? Похоже, для этого следует использовать сканирование диапазона индексов.   -  person kfinity    schedule 17.12.2018
comment
Интересно, может ли это быть лучше реализовано в виде материализованного представления? Однако существуют ограничения на то, когда материализованное представление может использовать преимущества быстрого обновления (т. е. обновления только с измененными записями), что может сделать его неподходящим для вашей цели.   -  person Boneist    schedule 18.12.2018


Ответы (2)


Пара идей: 1. Создайте таблицу для хранения последнего DML по имени таблицы, а затем создайте простой триггер для таблицы для обновления метатаблицы. 2. Создайте в таблице журнал материализованного представления и используйте данные из журнала для определения изменений.

person Stephen Caggiano    schedule 17.12.2018

Если есть архивные журналы за период поиска. Можно использовать утилиту LogMiner. Например:

insert into "ASOUP"."US"("KEY_COLUMN","COD_ROAD","COD_COMPUTER","COD_STATION_OPER","NUMB_TRAIN","STAT_CREAT","NUMB_SOSTAVA","STAT_APPOINT","COD_OPER","DIRECT_1","DIRECT_2","DATE_OPER","PARK","PATH","LOCOMOT","LATE","CAUSE_LATE","COD_CONNECT","CATEGORY","TIME") values ('42018740','988','0','9200','2624','8642','75','9802','1','8891','0',TO_DATE('18-Dec-2018', 'DD-Mon-RRRR'),'0','0','0','0','0','0',NULL,TO_DATE('18-Dec-2018', 'DD-Mon-RRRR'));

     select name, first_time,  next_time
     from v$archived_log
     where first_time >sysdate -3/24

/oracle/app/oracle/product/11.2/redolog/edcu/1_48060_769799469.dbf  18-дек-2018 09:03:06    18-дек-2018 10:22:00   
/oracle/app/oracle/product/11.2/redolog/edcu/1_48061_769799469.dbf  18-дек-2018 10:22:00    18-дек-2018 10:30:02   
/oracle/app/oracle/product/11.2/redolog/edcu/1_48062_769799469.dbf  18-дек-2018 10:30:02    18-дек-2018 10:56:07

Запустите утилиту logminer.

EXECUTE DBMS_LOGMNR.add_logfile(LOGFILENAME => '/oracle/app/oracle/product/11.2/redolog/edcu/1_48060_769799469.dbf', OPTIONS => DBMS_LOGMNR.NEW); 
EXECUTE DBMS_LOGMNR.add_logfile(LOGFILENAME => '/oracle/app/oracle/product/11.2/redolog/edcu/1_48061_769799469.dbf', OPTIONS => DBMS_LOGMNR.addfile); 
EXECUTE DBMS_LOGMNR.add_logfile(LOGFILENAME => '/oracle/app/oracle/product/11.2/redolog/edcu/1_48062_769799469.dbf', OPTIONS => DBMS_LOGMNR.addfile); 

EXECUTE DBMS_LOGMNR.START_LOGMNR(OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG);

SELECT scn,ROW_ID,to_char(timestamp,'DD-MM-YYYY HH24:MI:SS'),
table_name,seg_name,operation,  sql_redo,sql_undo
 FROM v$logmnr_contents
where seg_owner='ASOUP' and table_name='US'



SCN                ROW_ID           TIMESTAMP      TABLE_NAME    SEG_NAME OPERATION                              SQL_REDO  SQL_UNDO                                            


1398405575908  AAA3q2AAoAACFweABi   18-12-2018 09:03:15 US  US,ADCU201902   INSERT  insert into "ASOUP"."US"("KEY_COLUMN","COD_ROAD","COD_COMPUTER","COD_STATION_OPER","NUMB_TRAIN","STAT_CREAT","NUMB_SOSTAVA","STAT_APPOINT","COD_OPER","DIRECT_1","DIRECT_2","DATE_OPER","PARK","PATH","LOCOMOT","LATE","CAUSE_LATE","COD_CONNECT","CATEGORY","TIME") values ('42018727','988','0','8800','4404','1','895','8800','1','8838','0',TO_DATE('18-Dec-2018', 'DD-Mon-RRRR'),'4','2','0','0','0','0',NULL,TO_DATE('18-Dec-2018', 'DD-Mon-RRRR'));  delete from "ASOUP"."US" where "KEY_COLUMN" = '42018727' and "COD_ROAD" = '988' and "COD_COMPUTER" = '0' and "COD_STATION_OPER" = '8800' and "NUMB_TRAIN" = '4404' and "STAT_CREAT" = '1' and "NUMB_SOSTAVA" = '895' and "STAT_APPOINT" = '8800' and "COD_OPER" = '1' and "DIRECT_1" = '8838' and "DIRECT_2" = '0' and "DATE_OPER" = TO_DATE('18-Dec-2018', 'DD-Mon-RRRR') and "PARK" = '4' and "PATH" = '2' and "LOCOMOT" = '0' and "LATE" = '0' and "CAUSE_LATE" = '0' and "COD_CONNECT" = '0' and "CATEGORY" IS NULL and "TIME" = TO_DATE('18-Dec-2018', 'DD-Mon-RRRR') and ROWID = 'AAA3q2AAoAACFweABi';

Вы можете увидеть вставленную строку без полного сканирования:

select * from asoup.us where ROWID = 'AAA3q2AAoAACFweABi'; 
person Dmitry Demin    schedule 18.12.2018