Найти имя таблицы из файла v $ data. Имя Колум - PullRequest
3 голосов
/ 06 августа 2011

Когда вы смотрите на события ожидания (то есть с Toad), вы видите параметр файла #. Как я могу получить более полезную информацию в виде имени таблицы.

Можно ли узнать даже количество записей, которые читаются этой таблицей?

На другом форуме я нашел этот совет, но, похоже, он не работает.

select segment_name
from dba_extents ext
where ext.file_id = 828
            and 10711 between ext.block_id and ext.block_id + ext.blocks - 1
            and rownum = 1

1 Ответ

7 голосов
/ 06 августа 2011

Давайте поговорим о файлах, блоках, сегментах и ​​экстентах.

Сегмент - это объект базы данных, который хранится.Это может быть таблица, индекс, (под) раздел, кластер или большой объект.В основном вас заинтересуют таблицы и индексы.

Сегмент состоит из экстентов.Если вы думаете о сегменте как о книге, то степень - это глава.Сегмент (как правило) начинается как минимум с одного экстента.Когда ему нужно хранить больше данных и ему не хватает места в существующих экстентах, он добавляет еще один экстент в сегмент.

Экстент живет в файле данных.Файл данных может иметь множество экстентов, каждый из которых начинается в другой точке файла и имеет размер.У вас может быть один экстент из 15 блоков, начиная с файла 1 в блоке 10.

Событие ожидания должно идентифицировать файл и блок (и строку).Если ваше событие ожидания относится к файлу № 1 и блоку 12, вы переходите к USER_EXTENTS (или DBA_EXTENTS) и ищите экстент в файле № 1, где 12 находится между местоположением начального блока и местоположением начального блока плюс количество блоков.Таким образом, блок 12 будет между начальным блоком 10 и конечным блоком 25 (начальный плюс размер).

Как только вы определили экстент, вы отслеживаете его до его родительского сегмента (USER_SEGMENTS / DBA_SEGMENTS), который даст вамимя таблицы / индекса.


Теоретический SQL выглядит следующим образом:

select username, sid, serial#, 
       row_wait_obj#, row_wait_file#, row_wait_block#, row_wait_row#,
       ext.*
from v$session s
     join dba_extents ext on ext.file_id = row_wait_file#
     and row_wait_block# between ext.block_id and ext.block_id + ext.blocks - 1
where username = 'HR'
and status = 'ACTIVE'

Для этого я намеренно заблокировал сеанс, чтобы он ожидал блокировки строки.

828 - довольно большой идентификатор файла.Это не невозможно, но это необычно.Сделайте выбор из DBA_DATA_FILES и посмотрите, есть ли у вас такой файл.Если нет, и у вас есть только несколько файлов, посмотрите на все объекты, которые соответствуют критериям "10711 between ext.block_id and ext.block_id + ext.blocks - 1", без идентификатора файла.Вы должны быть в состоянии найти вероятного кандидата оттуда.

Исключение составляют случаи, когда проблема возникла во временном сегменте.Так как они удаляются в конце операции, постоянный объект не записывается.В этом случае «имя» таблицы / индекса неприменимо, и вам нужно решить любую проблему производительности другим способом (например, посмотреть на SQL и его план объяснения и выяснить, правильно ли оно использовать много временного пространства).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...