Запрос для проверки полного сканирования схемы для таблиц в Oracle DB

#oracle #plsql

#Oracle #plsql

Вопрос:

Привет, у меня есть требование просмотреть схему и определить таблицы, которые являются избыточными (кандидаты на удаление), поэтому я сделал выбор в DBA_Dependencies, чтобы проверить, используются ли таблицы в любом из типов объектов DB, таких как (Процедура, тело пакета, представления, материализованные представления ….) я смог найти некоторые таблицы и исключил таблицы, поскольку мне также нужно зафиксировать общее количество, когда таблица была загружена / использована в последний раз, есть ли автоматический способ выбрать только выбранные таблицы (не найдены в списке зависимостей) и зафиксировать количество, а также когда оно было использовано / загружено

Сложность — так много таблиц 500

я использовал приведенный ниже запрос

Запрос 1

 select table_name, 
       to_number(extractvalue(xmltype(dbms_xmlgen.getxml('select count(*) c from '||owner||'.'||table_name)),'/ROWSET/ROW/C')) as count
from all_tables
where owner = 'SCHEMA_NAME'
 

Запрос 2

 select owner, table_name, num_rows, sample_size, last_analyzed from all_tables;
 

Результат запроса 1

Filter Имя_таблицы=CUST_ORDER

 OWNER TABLE_NAME COUNT SAMPLE_SIZE LAST_ANALYZED
ABCD  CUST_ORDER  1083     1023       01.01.2020
 

Результат запроса 2

Filter Имя_таблицы=CUST_ORDER

 OWNER TABLE_NAME NUM_ROWS SAMPLE_SIZE LAST_ANALYZED
ABCD  CUST_ORDER  1023     1023       01.01.2020
 

Вопрос

Запрос 1 — Результаты не совпадают при сравнении с запросом 2, поскольку в обоих запросах применяется одна и та же таблица и фильтр, и почему результаты не совпадают ?

но когда я случайно проверил другой фильтр, он соответствует, знает ли кто-нибудь причину?

При дальнейшем тестировании я столкнулся с ошибкой, что эта ошибка означает разрешения?

 ORA-29913: error in executing ODCIEXTTABLEOPEN callout
ORA-29400: data cartridge error
KUP-04040: file **-**.csv in ****_***_***_***** not found
29913. 00000 -  "error in executing %s callout"
*Cause:    The execution of the specified callout caused an error.
*Action:   Examine the error messages take appropriate action.
 

Комментарии:

1. Эта ошибка встречается только для определенной схемы, а не для всех схем

Ответ №1:

Число, которое вы видите all_tables , — это момент времени, фиксирующий количество строк. Он будет обновлен только в том случае, если статистика будет перестроена для этой таблицы.

Вот пример:

 CREATE TABLE t1 AS
SELECT *
  FROM all_objects;

SELECT t.num_rows
  FROM all_tables t
 WHERE t.table_name = 'T1';
-- 78570

SELECT COUNT(*)
  FROM t1;
-- 78570
 

Статистика и физическое количество строк совпадают!

 INSERT INTO t1
  SELECT *
    FROM all_objects ao
   WHERE rownum <= 5;
-- 5 rows inserted

SELECT t.num_rows
  FROM all_tables t
 WHERE t.table_name = 'T1';
-- 78570

SELECT COUNT(*)
  FROM t1;
-- 78575
 

Здесь мы имеем несоответствие, потому что строки были вставлены (или, возможно, даже удалены), но статистика для таблицы не была обновлена. Давайте обновим их:

 BEGIN
  dbms_stats.gather_table_stats(ownname => 'SCHEMA',
                                tabname => 'T1');
END;
/

SELECT t.num_rows
  FROM all_tables t
 WHERE t.table_name = 'T1';
-- 78575
 

Теперь вы можете увидеть совпадение строк. Использование значения из all_tables может быть достаточно хорошим для вашего исследования (и, безусловно, будет быстрее запрашивать, чем подсчитывать каждую таблицу).

Комментарии:

1. Большое спасибо за объяснение с примером, это полезно

Ответ №2:

Запрос — 1 — это фактические данные таблицы и, следовательно, это точные данные. Можно полагаться на вывод этого запроса.

Запрос — 2 не является фактическими данными. Это данные, полученные при последнем анализе таблицы, и не следует зависеть от этого запроса для определения количества записей в таблице.

Вы можете собрать статистику по этой таблице и выполнить запрос-2, тогда вы найдете те же данные, что и запрос-1

Если записи не вставляются или не удаляются из таблицы после сбора статистики, то данные запроса-1 и запроса-2 будут совпадать для этой таблицы.

Комментарии:

1. Большое спасибо, это простое и понятное объяснение

2. @rakseh Также статистика собирается с использованием процесса выборки. При настройках по умолчанию dbms_stats может считывать все строки и фиксировать точное количество, или он может решить использовать меньшую выборку и экстраполировать вверх. Статистика должна быть достаточно близкой, чтобы оптимизатор мог выбрать наилучший подход, и не ожидается, что она будет соответствовать фактическому количеству каждый раз.

3. @WilliamRobertson Начиная с 11g, опция сбора статистики по умолчанию использует алгоритм нескольких различных значений, который сканирует всю таблицу и всегда возвращает точное количество строк. (Хотя другая статистическая информация, например гистограммы, может использовать отдельный проход и выборку.)

4. @JonHeller Я заметил, что он, как правило, дает точное количество, но я не знал, что это гарантировано. Спасибо!