Иерархический запрос Oracle с иерархией, примененной к подмножествам - PullRequest
0 голосов
/ 09 мая 2018

Я создаю специальный инструмент для мониторинга блокировки БД для Oracle SE.По сути, у меня есть задание планировщика, которое каждые 10 секунд делает снимок информации о сеансе gv $ и сохраняет его в пользовательской таблице ashstat_data.

А сейчас я пытаюсь создать представление для отображения цепочек блокировки сеансов в иерархическом формате для удобства.,Представление основано на иерархическом выборе, который показывает заблокированные сеансы как дочерние при блокировании родительского сеанса:

with l_snap as
(select * 
from ashstat_data
where sample_time>sysdate - interval '10' second )
SELECT 
s.sample_time,
' '||LPAD('-', (LEVEL-1), '-' ) || SESSION_ID asid,
s.wait_class,
s.event,
s.LOGON_TIME,
s.sql_id
FROM l_snap s
natural join dba_users d
inner join dba_objects do on s.LOCKED_OBJECT_ID=do.object_id
WHERE s.SESSION_ID IN 
(SELECT blocking_session FROM l_snap where blocking_session is not null)
OR s.blocking_session IS NOT NULL
CONNECT BY PRIOR 
 s.SESSION_ID=s.blocking_session
START WITH s.blocking_session IS NULL
;

И до сих пор это работает просто идеально, только если я выбираю данные из одного снимка (where sample_time>sysdate - interval '10' second):

SAMPLE_TIME              ASID   WAIT_CLASS  LOGON_TIME          SQL_ID
5/9/2018 16:13:08.173    302    Idle        05/09/2018 11:33:57 
5/9/2018 16:13:08.173    -594   Application 05/09/2018 11:34:01 0wvbggc3p3swx
5/9/2018 16:13:08.173    -646   Application 05/09/2018 11:34:07 0wvbggc3p3swx

Но если я выбираю записи из нескольких моментальных снимков (т. Е. (where sample_time>sysdate - interval '12' second), он упорядочивает их на основе соединения по условию:

SAMPLE_TIME              ASID   WAIT_CLASS  LOGON_TIME          SQL_ID
5/9/2018 16:17:18.166    302    Idle        05/09/2018 11:33:57 
5/9/2018 16:17:18.166    -594   Application 05/09/2018 11:34:01 0wvbggc3p3swx
5/9/2018 16:17:08.170    -594   Application 05/09/2018 11:34:01 0wvbggc3p3swx
5/9/2018 16:17:18.166    -646   Application 05/09/2018 11:34:07 0wvbggc3p3swx
5/9/2018 16:17:08.170    -646   Application 05/09/2018 11:34:07 0wvbggc3p3swx
5/9/2018 16:17:08.170    302    Idle        05/09/2018 11:33:57 
5/9/2018 16:17:18.166    -594   Application 05/09/2018 11:34:01 0wvbggc3p3swx
5/9/2018 16:17:08.170    -594   Application 05/09/2018 11:34:01 0wvbggc3p3swx
5/9/2018 16:17:18.166    -646   Application 05/09/2018 11:34:07 0wvbggc3p3swx
5/9/2018 16:17:08.170    -646   Application 05/09/2018 11:34:07 0wvbggc3p3swx

Чего я хотел бы достичьзаключается в том, что цепочка блокировок представлена ​​для каждого снимка в отдельности, поэтому последний результат выбора будет выглядеть следующим образом для всех собранных данных:

SAMPLE_TIME              ASID   WAIT_CLASS  LOGON_TIME          SQL_ID
5/9/2018 16:17:18.166    302    Idle        05/09/2018 11:33:57 
5/9/2018 16:17:18.166    -594   Application 05/09/2018 11:34:01 0wvbggc3p3swx
5/9/2018 16:17:18.166    -646   Application 05/09/2018 11:34:07 0wvbggc3p3swx
5/9/2018 16:17:08.170    302    Idle        05/09/2018 11:33:57 
5/9/2018 16:17:08.170    -594   Application 05/09/2018 11:34:01 0wvbggc3p3swx
5/9/2018 16:17:08.170    -646   Application 05/09/2018 11:34:07 0wvbggc3p3swx

1 Ответ

0 голосов
/ 09 мая 2018

Возможно, вам нужно добавить sample_time в ваше предложение CONNECT BY:

with l_snap as
(select * 
from ashstat_data
where sample_time>sysdate - interval '10' second )
SELECT 
s.sample_time,
' '||LPAD('-', (LEVEL-1), '-' ) || SESSION_ID asid,
s.wait_class,
s.event,
s.LOGON_TIME,
s.sql_id
FROM l_snap s
natural join dba_users d
inner join dba_objects do on s.LOCKED_OBJECT_ID=do.object_id
WHERE s.SESSION_ID IN 
(SELECT blocking_session FROM l_snap where blocking_session is not null)
OR s.blocking_session IS NOT NULL
CONNECT BY PRIOR 
 s.SESSION_ID=s.blocking_session
 and prior s.sample_time = s.sample_time
START WITH s.blocking_session IS NULL
;
...