Факт 1
Точно так же он поступает и при вызове агрегатной функции collect.
-- Сначала проверим есть ли такие типы DB11G/XTENDER> select t.type_name,t.type_name,t.typecode 2 from dba_types t 3 where t.type_name like 'SYSTP%'; no rows selected -- Выполним запрос с collect DB11G/XTENDER> select collect(level) from dual connect by level<=10; COLLECT(LEVEL) ------------------------------------------------------------------------- SYSTPZvGjVQTySRSjYVlHXyEE2Q==(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) 1 row selected. -- Проверим снова и увидим что появился новый тип SYSTP% DB11G/XTENDER> select t.type_name,t.type_name,t.typecode 2 from dba_types t 3 where t.type_name like 'SYSTP%'; TYPE_NAME TYPE_NAME TYPECODE ------------------------------ ------------------------------ ------------ SYSTPZvGjVQTySRSjYVlHXyEE2Q== SYSTPZvGjVQTySRSjYVlHXyEE2Q== COLLECTIONИ еще выберем данные по нему из sys.obj$ - это нам потом пригодится:
DB11G/XTENDER> select obj#,type#,ctime,mtime,stime,status 2 from sys.obj$ o$ 3 where o$.name = 'SYSTPZvGjVQTySRSjYVlHXyEE2Q=='; OBJ# TYPE# CTIME MTIME STIME ------ ------ ------------------- ------------------- ------------------- 103600 10 28.04.2012 01:02:35 28.04.2012 01:02:35 28.04.2012 01:02:35Это абсолютно закономерно - нельзя вернуть клиенту информацию не описав ее.
Факт №2
Теперь зная, что тип создается, интересно что потом будет с этим типом: будет ли он удален после фетча или после отключения клиента? Например, при удалении пакетного типа автоматически дропался и доменный тип, будет ли здесь аналогичное автоматическое удаление?Согласно Bug 4033868: COLLECT FUNCTION LEAVES TEMPORARY SYS TYPES BEHIND этот баг решен в "11.0", но я тестирую на 11.2.0.1 и элементарная проверка после дисконнекта показала, что тип продолжает существовать до рестарта инстанса, однако на самом деле даже после этого он остается, но в dba_objects уже не выводится.
Я дропну его сам, чтобы лишний раз не рестартить инстанс - это абсолютно аналогично тому как oracle "удаляет" этот тип в 11.2:
DB11G/XTENDER> drop type "SYSTPZvGjVQTySRSjYVlHXyEE2Q=="; Type dropped.А теперь проверим:
DB11G/XTENDER> select * from dba_types where type_name='SYSTPZvGjVQTySRSjYVlHXyEE2Q=='; no rows selectedВроде удалили, однако посмотрим в sys.obj$:
DB11G/XTENDER> select obj#,type#,ctime,mtime,stime,status 2 from sys.obj$ o$ 3 where o$.name = 'SYSTPZvGjVQTySRSjYVlHXyEE2Q=='; OBJ# TYPE# CTIME MTIME STIME ------ ------ ------------------- ------------------- ------------------- 103600 10 28.04.2012 01:02:35 28.04.2012 01:40:37 31.12.4712 23:59:59Как видите, объект остался, но с type#=10 и с stime равным последней дате 4712 года, а раньше было type#=13 и stime=mtime=ctime, а в 10.2 при ручном дропе этого типа никаких записей не оставалось. Поясню соответствия полей из sys.obj$ и dba_objects, чтобы было понятней: obj# - object_id, type# ~ код типа, ctime,mtime,stime - created, last_ddl_time, timestamp соответственно. По коду представления dba_objects мы увидим, что type# = 10 - это якобы "NON-EXISTENT" и выводить его не нужно.
and (o.type# not in (1 /* INDEX - handled below */, 10 /* NON-EXISTENT */)А установка даты в 31.12.4712 23:59:59 указывает на его неактуальность - уж слишком далекое будущее :)
Факт №3
Теперь перейдем к тому, что меня собственно заставило повозиться с collect: ошибки с параллельным выполнением collect (обсуждение на форуме с указанием и подробным описанием Bug 11906197).Вообще collect довольно глючная штука, я и сам на это уже неоднократно нарывался, и на металинке много различных багов связанных с collect(например, "Bug 8912282: COLLECT+UNIQUE+ORDER DOES NOT REMOVE DUPLICATES", "Bug 6145841: ORA-600[KOLOGSF2] ON CAST(COLLECT(..)) CALL","Bug 11802848: CAST/COLLECT DOES NOT WORK IN VERSION 11.2.0.2 WITH TYPE SYS.DBMS_DEBUG_VC2COLL", "Bug 6996176: SELECT COLLECT DISTINCT GROUP BY STATEMENT RETURNS DUPLICATE VALUES").
create table test_parallel parallel 8 as select mod(level,8) a, level b from dual connect by level<=1000; create index IX_TEST_PARALLEL on TEST_PARALLEL (A);
DB11G/XTENDER> select/*+ PARALLEL(2)*/ cast(collect(a) as number_table) from test_parallel ; select/*+ PARALLEL(2)*/ cast(collect(a) as number_table) from test_parallel * ERROR at line 1: ORA-12801: error signaled in parallel query server P000 ORA-21710: argument is expecting a valid memory address of an object Elapsed: 00:00:00.12 DB11G/XTENDER> select cast(collect(b) as number_table) from test_parallel group by a; select cast(collect(b) as number_table) from test_parallel group by a * ERROR at line 1: ORA-12805: parallel query server died unexpectedly Elapsed: 00:00:17.57
create or replace type ncollect_type as object ( data sys.ku$_objnumset, static function ODCIAggregateInitialize ( sctx in out ncollect_type ) return number , member function ODCIAggregateIterate ( self in out ncollect_type , val in number ) return number , member function ODCIAggregateDelete ( self in out ncollect_type, val in number ) return number , member function ODCIAggregateTerminate ( self in ncollect_type, returnval out sys.ku$_objnumset, flags in number ) return number , member function ODCIAggregateMerge ( self in out ncollect_type, ctx2 in ncollect_type ) return number ) / create or replace type body ncollect_type is static function ODCIAggregateInitialize ( sctx in out ncollect_type ) return number is begin sctx := ncollect_type( sys.ku$_objnumset()) ; return ODCIConst.Success ; end; member function ODCIAggregateIterate ( self in out ncollect_type , val in number ) return number is begin self.data:=self.data multiset union sys.ku$_objnumset(val); return ODCIConst.Success; end; member function ODCIAggregateDelete ( self in out ncollect_type, val in number ) return number is begin self.data:=self.data multiset except sys.ku$_objnumset(val); return ODCIConst.Success; end; member function ODCIAggregateTerminate ( self in ncollect_type , returnval out sys.ku$_objnumset , flags in number ) return number is begin returnval:=self.data; return ODCIConst.Success; end; member function ODCIAggregateMerge ( self in out ncollect_type , ctx2 in ncollect_type ) return number is begin self.data := self.data multiset union ctx2.data; return ODCIConst.Success; end; end; /
Вариант | Время(сек) |
---|---|
select/*+ NO_PARALLEL*/ cast(collect(b) as number_table) from test_parallel group by a; | 0.03 |
select/*+ NO_PARALLEL*/ ncollect(b) from test_parallel group by a | 0.08 |
select ncollect(b) from test_parallel group by a; | 0.07 |
select/*+ NO_PARALLEL*/ collect(a) from test_parallel; | 0.02 |
select/*+ NO_PARALLEL*/ ncollect(a) from test_parallel | 0.18 |
select ncollect(a) from test_parallel; | 0.19 |
select/*+ NO_PARALLEL*/ collect(b) from test_parallel; | 0.02 |
select/*+ NO_PARALLEL*/ ncollect(b) from test_parallel | 0.18 |
select ncollect(b) from test_parallel; | 0.06 |
Comments
Отправить комментарий