Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2 3   вперед  Ctrl      все
 Инсерт не дает делать селект  [new]
Бронеконь
Guest
Делается инсерт из одной таблицы в другую по курсору (ну чтобы можно было каждые допустим 1000 записей делать коммит, что и делается)
Короче

begin
for r in (select * from....)
loop
  begin
    insert into .... values(r...., r..., r... и т.д.);
  exception when others then null;
  end;
  a:=a+1;
  if a=1000 then 
     commit;
     a:=0;
  end if;  
end loop;
end;

Так вот сначала можно было смотреть солько строк он уже перенес из одной таблицы в другую. Но спустя 12 часов работы скрипта уже не дает - бесполезно селект каунт виснет надолго. хотя скрипт еще отрабатывает и инсерты идут видимо.
7 апр 06, 15:52    [2537266]     Ответить | Цитировать Сообщить модератору
 Re: Инсерт не дает делать селект  [new]
alex-ls
Member

Откуда: Иркутская обл - Пенза - Москва
Сообщений: 6919
зачем вам там commit нужен?
7 апр 06, 15:58    [2537299]     Ответить | Цитировать Сообщить модератору
 Re: Инсерт не дает делать селект  [new]
Tolmachov Dmitiry
Member

Откуда: Москва, Пенза
Сообщений: 1520
Естественно, что уже нельзя посчитать! У тебя поди в таблице уже очень прилично записей для подсчета. Поди еще неубитые старые сессии болтаются. Так что Oracle не осиляет Select count(*). Модифицируй свой алгоритм. Можно писать вставленное кол-во записей в таблицу. Все равно записи считаешь. Так же можно выстреливать в pipe.
7 апр 06, 15:58    [2537301]     Ответить | Цитировать Сообщить модератору
 Re: Инсерт не дает делать селект  [new]
Бронеконь
Guest
да записей там около 12 млн
автор
Можно писать вставленное кол-во записей в таблицу

у меня тоже была такая мысль, но уже поздняк наверно - пусть дорабатывает?

автор
зачем вам там commit нужен?


просто если тупо инсерт-селект - то там столько памяти жраться будет - нереально :) ну 10 млн записей елки!... :)
7 апр 06, 16:01    [2537324]     Ответить | Цитировать Сообщить модератору
 Re: Инсерт не дает делать селект  [new]
alex-ls
Member

Откуда: Иркутская обл - Пенза - Москва
Сообщений: 6919
Бронеконь

автор
зачем вам там commit нужен?


просто если тупо инсерт-селект - то там столько памяти жраться будет - нереально :) ну 10 млн записей елки!... :)

нет, ну не через 1000 же строк, хоть расширьте диапазончик-то...
7 апр 06, 16:04    [2537346]     Ответить | Цитировать Сообщить модератору
 Re: Инсерт не дает делать селект  [new]
StarWoofy
Member

Откуда: Moscow
Сообщений: 1005
автор
Можно писать вставленное кол-во записей в таблицу

Добавить что то типа вывода dbms_output.put_line
и не обнулять счетчик "a", а проверять делится ли он на 1000
Например.
:)
7 апр 06, 16:06    [2537357]     Ответить | Цитировать Сообщить модератору
 Re: Инсерт не дает делать селект  [new]
Q u a d r o
Member

Откуда: Canada
Сообщений: 1987
Бронеконь
просто если тупо инсерт-селект - то там столько памяти жраться будет - нереально :) ну 10 млн записей елки!... :)


Извините - глупости. Своим процедурным циклом вы только делаете вещи настолько медленно, насколько это только возможно.

Инсерт записей не будет "жрать" память:

SQL> create table test as select * from all_objects where 1=0;

Table created.

SQL> select a.name, b.value
  2   from v$statname a, v$mystat b
  3   where a.statistic#=b.statistic#
  4    and a.name like '%ga memory%';

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
session uga memory                                                  3045036
session uga memory max                                              3299416
session pga memory                                                  4185684
session pga memory max                                              8511060

SQL> insert /*+ append */ into test select * from test;

0 rows created.

SQL> drop table tets purge;
drop table tets purge
           *
ERROR at line 1:
ORA-00942: table or view does not exist


SQL> drop table test;

Table dropped.

SQL> create table test as select * from all_objects;

Table created.

SQL> select a.name, b.value
  2   from v$statname a, v$mystat b
  3   where a.statistic#=b.statistic#
  4    and a.name like '%ga memory%';

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
session uga memory                                                  3045036
session uga memory max                                              3299416
session pga memory                                                  4185684
session pga memory max                                              8511060

SQL> insert /*+ append */ into test select * from test;

49268 rows created.

SQL> commit;

Commit complete.

SQL> select a.name, b.value
  2   from v$statname a, v$mystat b
  3   where a.statistic#=b.statistic#
  4    and a.name like '%ga memory%';

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
session uga memory                                                  3045036
session uga memory max                                              3299416
session pga memory                                                  4185684
session pga memory max                                              8511060

SQL> insert /*+ append */ into test select * from test;

98536 rows created.

SQL> commit;

Commit complete.

SQL> select a.name, b.value
  2   from v$statname a, v$mystat b
  3   where a.statistic#=b.statistic#
  4    and a.name like '%ga memory%';

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
session uga memory                                                  3045036
session uga memory max                                              3299416
session pga memory                                                  4185684
session pga memory max                                              8511060

SQL> insert /*+ append */ into test select * from test;

197072 rows created.

SQL> commit;

Commit complete.

SQL> select a.name, b.value
  2   from v$statname a, v$mystat b
  3   where a.statistic#=b.statistic#
  4    and a.name like '%ga memory%';

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
session uga memory                                                  3045036
session uga memory max                                              3299416
session pga memory                                                  4185684
session pga memory max                                              8511060

SQL> insert /*+ append */ into test select * from test;

394144 rows created.

SQL> commit;

Commit complete.

SQL> select a.name, b.value
  2   from v$statname a, v$mystat b
  3   where a.statistic#=b.statistic#
  4    and a.name like '%ga memory%';

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
session uga memory                                                  3045036
session uga memory max                                              3299416
session pga memory                                                  4185684
session pga memory max                                              8511060


как видите - с увеличением кол-ва вставляемых записей объём используемой сессией памяти не меняется.

перестаньте заниматься "процедурной ерундой" и дайте СУБД возможность самой делать то, для чего она была рождена - максимально эффективно.
7 апр 06, 16:15    [2537421]     Ответить | Цитировать Сообщить модератору
 Re: Инсерт не дает делать селект  [new]
softwarer
Member

Откуда: 127.0.0.1
Сообщений: 64026
Блог
В целом есть два варианта. Можно оставить скрипт работать на выходные. Можно вырубить и написать вместо него insert/select с append-ом - не знаю что за сервер, но за полчаса думаю справится.
7 апр 06, 16:17    [2537441]     Ответить | Цитировать Сообщить модератору
 Re: Инсерт не дает делать селект  [new]
andrey_anonymous
Member

Откуда: Москва
Сообщений: 18399
Q u a d r o
insert select

Вот только в rollback надо поместиться, а в остальном - правы :)
7 апр 06, 16:19    [2537452]     Ответить | Цитировать Сообщить модератору
 Re: Инсерт не дает делать селект  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10053
Q u a d r o
перестаньте заниматься "процедурной ерундой" и дайте СУБД возможность самой делать то, для чего она была рождена - максимально эффективно.


Assuming there is enough UNDO, since UNDO rather than memory "жраться будет".

SY.
7 апр 06, 16:24    [2537489]     Ответить | Цитировать Сообщить модератору
 Re: Инсерт не дает делать селект  [new]
Q u a d r o
Member

Откуда: Canada
Сообщений: 1987
SY
Assuming there is enough UNDO, since UNDO rather than memory "жраться будет".


no it would not since /*+ appned */ hint bypasses UNDO
7 апр 06, 16:28    [2537514]     Ответить | Цитировать Сообщить модератору
 Re: Инсерт не дает делать селект  [new]
andrey_anonymous
Member

Откуда: Москва
Сообщений: 18399
Q u a d r o
SY
Assuming there is enough UNDO, since UNDO rather than memory "жраться будет".
no it would not since /*+ appned */ hint bypasses UNDO

А что говорите у нас на standby будет?
7 апр 06, 16:30    [2537531]     Ответить | Цитировать Сообщить модератору
 Re: Инсерт не дает делать селект  [new]
Q u a d r o
Member

Откуда: Canada
Сообщений: 1987
andrey_anonymous
А что говорите у нас на standby будет?


На stand by пойдёт redo. Поскольку /*+ append */ всегда вставляет выше HWM в таблице - commit либо зафиксирует всё, либо Oracle просто "забудет" о проделанной работе.

SQL> insert /*+ append */ into test select * from test;

49269 rows created.

SQL> select used_ublk
  2   from v$transaction
  3   where addr=(
  4    select taddr
  5     from v$session a
  6     where sid=(select sid from v$mystat where rownum=1)
  7    );

 USED_UBLK
----------
         1

SQL> commit;

Commit complete.

мы использовали 1 блок в UNDO - эта цифра не будет зависеть от кол-ва вставляемых строк

SQL> insert into test select * from all_objects;

49269 rows created.

SQL> select used_ublk
  2   from v$transaction
  3   where addr=(
  4    select taddr
  5     from v$session a
  6     where sid=(select sid from v$mystat where rownum=1)
  7    )
  8  ;

 USED_UBLK
----------
        23

и 23 блока в случае conventional insert на те же 49269 строк - эта цифра будет будет увеличиваться при увеличении кол-ва строк.
7 апр 06, 16:41    [2537599]     Ответить | Цитировать Сообщить модератору
 Re: Инсерт не дает делать селект  [new]
?
Guest
Quadro
мы использовали 1 блок в UNDO - эта цифра не будет зависеть от кол-ва вставляемых строк

В UNDO записываются заголовки пустых блоков, и что, только один блок в UNDO они все займут?
7 апр 06, 16:51    [2537654]     Ответить | Цитировать Сообщить модератору
 Re: Инсерт не дает делать селект  [new]
andrey_anonymous
Member

Откуда: Москва
Сообщений: 18399
Q u a d r o
andrey_anonymous
А что говорите у нас на standby будет?
На stand by пойдёт redo.

А он будет, этот redo? При direct load?
Как-то получили на standby currupted, больше не экспериментировали :)
7 апр 06, 16:56    [2537694]     Ответить | Цитировать Сообщить модератору
 Re: Инсерт не дает делать селект  [new]
Q u a d r o
Member

Откуда: Canada
Сообщений: 1987
им не нужно занимать никаких блоков в UNDO вообще, в этом единственном блоке просто содержится информация что у нас есть транзакция.

insert /*+ append */ получит эксклюзивную блокировку и начнёт вставлять выше HWM (выше HWM "ничего нет" - нам не нужно писать UNDO).

в случае commit - Oracle просто подвинет HWM.

в случае rollback - Oracle просто не будет двигать HWM и данные нише HWM просто "пропадут" сами собой.

никаких "откатов" в виде восстановления старых версий блоков здесь не нужно.

по этой же причине после /*+ append */ вы не сможете вставить в таблицу, не зафиксировав транзакцию - Oracle не будет знать куда вставлять (поскольку не понятно, где сейчас hwm и в каком состоянии находится таблица):

автор

SQL> insert /*+ append */ into test select * from test;

147807 rows created.

SQL> insert into test select * from all_objects;
insert into test select * from all_objects
*
ERROR at line 1:
ORA-12838: cannot read/modify an object after modifying it in parallel
7 апр 06, 17:00    [2537713]     Ответить | Цитировать Сообщить модератору
 Re: Инсерт не дает делать селект  [new]
Q u a d r o
Member

Откуда: Canada
Сообщений: 1987
andrey_anonymous
А он будет, этот redo? При direct load?


В 9iR2 /*+ append */ пишет redo если база в archive log и на сегменте нет nologging.

/*+ append */ всегда пишет rdo если у вас база в force logging.

До 9iR2 /*+ append */ действительно не писал redo по умолчанию.
7 апр 06, 17:02    [2537730]     Ответить | Цитировать Сообщить модератору
 Re: Инсерт не дает делать селект  [new]
andrey_anonymous
Member

Откуда: Москва
Сообщений: 18399
Q u a d r o
insert /*+ append */ получит эксклюзивную блокировку и начнёт вставлять выше HWM (выше HWM "ничего нет" - нам не нужно писать UNDO).

Q u a d r o, что будет на standby?
7 апр 06, 17:02    [2537733]     Ответить | Цитировать Сообщить модератору
 Re: Инсерт не дает делать селект  [new]
Заглянул
Member

Откуда: nowhere
Сообщений: 403
andrey_anonymous

Вот только в rollback надо поместиться, а в остальном - правы :)

andrey_anonymous

А он будет, этот redo? При direct load?

???
:)
7 апр 06, 17:05    [2537745]     Ответить | Цитировать Сообщить модератору
 Re: Инсерт не дает делать селект  [new]
?
Guest
Если на таблице есть индексы, при direct pass UNDO будет.
7 апр 06, 17:07    [2537755]     Ответить | Цитировать Сообщить модератору
 Re: Инсерт не дает делать селект  [new]
Q u a d r o
Member

Откуда: Canada
Сообщений: 1987
andrey_anonymous
Q u a d r o, что будет на standby?


не пойму в чем ваша проблема....

SQL> insert /*+ append */ into test select * from test;

98540 rows created.


Statistics
-------------------------------------------------------
        484  recursive calls
       1507  db block gets
       1495  consistent gets
        677  physical reads
   11173056  redo size
        666  bytes sent via SQL*Net to client
        581  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
      98540  rows processed

SQL> commit;

Commit complete.

11173056 bytes redo - вся вставка залогирована.

SQL> insert /*+ append */ into test select * from test;

197080 rows created.


Statistics
-------------------------------------------------------
       1153  recursive calls
       2999  db block gets
       3088  consistent gets
       1353  physical reads
      48772  redo size
        666  bytes sent via SQL*Net to client
        581  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          6  sorts (memory)
          0  sorts (disk)
     197080  rows processed

теперь 48772 - вставка не логируется и на standby мы получим "задницу" :-)

поэтому правильные базы при наличии standby работают в force logging:

SQL> alter database force logging;

Database altered.

SQL> insert /*+ append */ into test select * from test;

394160 rows created.


Statistics
----------------------------------------------------------
       1056  recursive calls
       5745  db block gets
       5717  consistent gets
       2907  physical reads
   44590436  redo size
        666  bytes sent via SQL*Net to client
        581  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
     394160  rows processed

снова все залогировалось.
7 апр 06, 17:07    [2537760]     Ответить | Цитировать Сообщить модератору
 Re: Инсерт не дает делать селект  [new]
Q u a d r o
Member

Откуда: Canada
Сообщений: 1987
сорри - в предыдущем посте во втором куке "потерялся" alter table test nologging:

SQL> alter table test nologging;

Table altered.

SQL> insert /*+ append */ into test select * from test;

197080 rows created.


Statistics
-------------------------------------------------------
       1153  recursive calls
       2999  db block gets
       3088  consistent gets
       1353  physical reads
      48772  redo size
        666  bytes sent via SQL*Net to client
        581  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          6  sorts (memory)
          0  sorts (disk)
     197080  rows processed
7 апр 06, 17:09    [2537769]     Ответить | Цитировать Сообщить модератору
 Re: Инсерт не дает делать селект  [new]
Бронеконь
Guest
insert /*+ append */ into test select * from test;

не катит однозначно, при таком варианте - виснет вся база. (из-за redo похоже) так что лучше по кусочкам с коммитами.
ну и в коде тоже аппенд хинт стоит
плюс в сесси на таблицу сделал nologging и увеличил размер сорт ареа сайз
ну да ладно оставлям на выходныем :)
7 апр 06, 17:09    [2537774]     Ответить | Цитировать Сообщить модератору
 Re: Инсерт не дает делать селект  [new]
HX
Member

Откуда: Moscow
Сообщений: 2454
andrey_anonymous
Q u a d r o
andrey_anonymous
А что говорите у нас на standby будет?
На stand by пойдёт redo.

А он будет, этот redo? При direct load?
Как-то получили на standby currupted, больше не экспериментировали :)

Надо было просто проверить v$datafile.unrecoverable_change# :-)
7 апр 06, 17:11    [2537792]     Ответить | Цитировать Сообщить модератору
 Re: Инсерт не дает делать селект  [new]
Q u a d r o
Member

Откуда: Canada
Сообщений: 1987
Бронеконь
(из-за redo похоже)


ну так увеличивайте размер или кол-во членов в redo.

insert /*+ append */ даже в Logging генерирует меньше redo - нам не нужно писать redo для Undo. Просто он работает намного быстрее чем ваш slow by slow процедурный цикл, и redo в единицу времени генерируется больше.
7 апр 06, 17:16    [2537825]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2 3   вперед  Ctrl      все
Все форумы / Oracle Ответить