Выборка данных с последующим обновлением.

Автор Uukrul, Лютий 19, 2009, 02:15:59 ПП

Попередня тема - Наступна тема

0 Користувачі і 1 Гість дивляться цю тему.

Uukrul

В общем есть запрос который выгребает данные во внутреннюю таблицу, например

DATA: BEGIN OF lt_int_file OCCURS 1,
    fld_1(18) TYPE c,
    fld_2(18) TYPE c,
    status(1) TYPE c,
END OF lt_int_file.

SELECT xxx.fld_1 zzz.fld_2 INTO CORRESPONDING FIELDS OF TABLE lt_int_file
FROM xxx
  JOIN zzzz
WHERE <разные ограничения>

* Далее делаем типа
UPDATE z_table
FROM TABLE lt_int_file.


Так вот, надо всем записям которые обновились для поля status например поставить значение 'U', т.е. в выборке такого поля нет, конструкции типа SELECT xxx.fld_1 zzz.fld_2 'U' as status INTO CORRESPONDING FIELDS OF TABLE lt_int_file, вроде как тоже нет, т.е. остается только пройтись

LOOP AT lt_int_file.
  lt_int_file-status = 'U'.
  MODIFY lt_int_file.
ENDLOOP.

* И дальше уже
UPDATE z_table
FROM TABLE lt_int_file.

Или есть идеи как это можно сделать по другом? Просто не очень хочется проходиться по всей выборке после SELECT-а ???

Dmitriy

  DATA: BEGIN OF lt_int_file OCCURS 1,
      fld_1(18) TYPE c,
      fld_2(18) TYPE c,
      status(1) TYPE c,
  END OF lt_int_file.
* В данном случае можно обойтись без INTO CORRESPONDING FIELDS,
* т.к. выбираемые поля во вн.табл. и выборке перечислены соответственно   
  SELECT xxx~fld_1 zzz~fld_2 INTO TABLE lt_int_file FROM xxx
    JOIN zzz ON (условия соединения)
    WHERE (разные ограничения).

Первое, что пришло на ум (возможно из-за неполного понимания всей задачи, стоящей "за кадром"): если мы проводим UPDATE dbtab из внутренней сразу всех записей без цикла, то не означает ли это, что установка поля status в строке ее эквивалента простому наличию строки? К тому же, лог, как я понял, не ведется...

Паганель

Цитата: Dmitriy від Лютий 19, 2009, 03:26:03 ПП
  DATA: BEGIN OF lt_int_file OCCURS 1,
      fld_1(18) TYPE c,
      fld_2(18) TYPE c,
      status(1) TYPE c,
  END OF lt_int_file.
* В данном случае можно обойтись без INTO CORRESPONDING FIELDS,
* т.к. выбираемые поля во вн.табл. и выборке перечислены соответственно   
  SELECT xxx~fld_1 zzz~fld_2 INTO TABLE lt_int_file FROM xxx
    JOIN zzz ON (условия соединения)
    WHERE (разные ограничения).

Первое, что пришло на ум (возможно из-за неполного понимания всей задачи, стоящей "за кадром"): если мы проводим UPDATE dbtab из внутренней сразу всех записей без цикла, то не означает ли это, что установка поля status в строке ее эквивалента простому наличию строки? К тому же, лог, как я понял, не ведется...


Не очень понял, что ты написал.

Реально, задача стоит в том, что бы проапдейтить табличку выборкой с нее же + еще кое-какие данные, и + установить статус.

Dmitriy

Цитата: Паганель від Лютий 19, 2009, 03:33:03 ПП
Не очень понял, что ты написал.
Реально, задача стоит в том, что бы проапдейтить табличку выборкой с нее же + еще кое-какие данные, и + установить статус.
Если поле status есть в z_table, то пардон, значит неправильно понял подоплеку. Скорее всего только в цикле.
 


Uukrul

Цитата: Dmitriy від Лютий 19, 2009, 03:48:34 ПП
Если поле status есть в z_table, то пардон, значит неправильно понял подоплеку. Скорее всего только в цикле.
Дело в том что если в выборку попадает так скажем 10 000 000 записей, то в цикле получается очень долго, вот и искались мысли, а нельзя ли как-то например при апдейте указать начальное значение для одного из полей. Похоже нельзя и надо вообще искать какой-то другой метод для контроля обновившихся записей.

Паганель

Цитата: Uukrul від Лютий 19, 2009, 03:53:43 ПП
Дело в том что если в выборку попадает так скажем 10 000 000 записей, то в цикле получается очень долго,

сделаем замер на реальных данных (джоб запускается в 10 утра)  ;)

Uukrul

Цитата: Паганель від Лютий 19, 2009, 03:57:44 ПП
сделаем замер на реальных данных (джоб запускается в 10 утра)  ;)
Да вообще-то это уже рабочий день полным ходом... какое нафиг утра  :D утра это часов в 5...

Паганель

Цитата: Uukrul від Лютий 19, 2009, 03:59:01 ПП
Да вообще-то это уже рабочий день полным ходом... какое нафиг утра  :D утра это часов в 5...

Раньше  нельзя, еще не все данные есть.

За последнее время статистика (до изменений):
4.003
3.648
2.349
2.047
3.797
4.086
2.762
3.439
посмотрим завтра

Uukrul



Uukrul

Цитата: Паганель від Лютий 19, 2009, 04:12:57 ПП
sm37, продолжительность выполнения.
Ну я бы замерял бы все таки время выборки и время выполнения LOOP AT. А так общее время выполнения, никак не корелируется с выборками.

Паганель

я просто посмотрю на сколько увеличилось время выполнения всей проги

Uukrul

Цитата: Паганель від Лютий 19, 2009, 04:16:18 ПП
я просто посмотрю на сколько увеличилось время выполнения всей проги
Да ну, меньше часа крутиться... это фигня еще  ;)

Dmitriy

Если сильно прижмет по быстродействию LOOP at ... assigning <> ... ENDLOOP, то сделайте табличку из 2-х ключевых полей: MANDT и STATUS, и вставьте туда 1 запись: MANDT = sy-mandt и STATUS = 'U'. Джоин - по манданту. Проверил - заполняется статус без цикла. ;)

Uukrul

Цитата: Dmitriy від Лютий 19, 2009, 05:08:57 ПП
TATUS, и вставьте туда 1 запись: MANDT = sy-mandt и STATUS = 'U'. Джоин - по манданту. Проверил - заполняется статус без цикла. ;)
Что-то я не понял мысли... можешь примером кода набросать?

Dmitriy

#16
Цитата: Uukrul від Лютий 19, 2009, 05:16:47 ПП
Что-то я не понял мысли... можешь примером кода набросать?
DATA: BEGIN OF lt_int_file OCCURS 1,
      fld_1(18) TYPE c,
      fld_2(18) TYPE c,
      status(1) TYPE c,
  END OF lt_int_file.
  DATA: ls type yxxx. "Тип нашей таблички с одной записью или без оной.
  SELECT SINGLE * INTO ls FROM yxxx.
  IF SY-SUBRC <> 0.
    ls-mandt = sy-mandt.
    ls-status = 'U'.
    INSERT INTO yxxx VALUES ls.
    COMMIT WORK AND WAIT.
  ENDIF.
* В данном случае можно обойтись без INTO CORRESPONDING FIELDS,
* т.к. выбираемые поля во вн.табл. и выборке перечислены соответственно   
  SELECT xxx~fld_1 zzz~fld_2 yxxx~status INTO TABLE lt_int_file FROM xxx
    JOIN zzz ON (условия соединения)
    JOIN yxxx ON zzz~mandt = yxxx~mandt
    WHERE (разные ограничения).


Uukrul

Ага ясно... а в принципе это таки да мысль.. сделать JOIN с табилице, т.е. там статусов напримеру у меня 5 штук. Вставить эти статусы и джойнить их  стем статусом который нужен, автоматически заливаем требуемое значение статуса в нашу выборку и LOOP по таблице для установки статуса уже не нужен...

Dmitriy

Цитата: Uukrul від Лютий 19, 2009, 05:35:29 ПП
Ага ясно... а в принципе это таки да мысль.. сделать JOIN с табилице, т.е. там статусов напримеру у меня 5 штук. Вставить эти статусы и джойнить их  стем статусом который нужен, автоматически заливаем требуемое значение статуса в нашу выборку и LOOP по таблице для установки статуса уже не нужен...
Ну про то, что целезообразно там все статусы завести я уже не стал писать. ;)

Паганель

1. Результат (запустил на выполнение перед отьездом с работы)
2.491 (правда данныех сейчас там мало, после всех обработок, лишнее данные удаляются), так что это не показатель, завтра, на реальных данных посмотрим.

Дима, по поводу LOOP at ... assigning <> ... ENDLOOP
2. Никак не привикну юзать данную конструкцию все постаринке
LOOP AT gt_sap_rest.
  gt_sap_rest-status = 2. " загруженно с магазина + расчитано в SAP
  MODIFY gt_sap_rest.
ENDLOOP.

3. Решение Димы, простое и оригинальное, как все гениальное  :), попробуемс ....
спасибо

Dmitriy

Цитата: Паганель від Лютий 19, 2009, 06:32:12 ПП
Дима, по поводу LOOP at ... assigning <> ... ENDLOOP
2. Никак не привикну юзать данную конструкцию все постаринке
LOOP AT gt_sap_rest.
  gt_sap_rest-status = 2. " загруженно с магазина + расчитано в SAP
  MODIFY gt_sap_rest.
ENDLOOP.
FIELD-SYMBOLS: <fs> LIKE LINE of gt_sap_rest.
LOOP AT gt_sap_rest ASSIGNING <fs>.
  <fs>-status = '2'. " - с одинарными кавычками, т.к. поле символьное, хотя SAP не ругается " загруженно с магазина + расчитано в SAP
ENDLOOP.

Дает существенное ускорение цикла в котором строки вн. таблицы модифицируются (особенно при большом к-ве записей), пора привыкать.


Uukrul

Однако подтверждаю, и так провел небольшой тест, есть табличка MSEG, система тестовая записей  123 226, сделана программка следующего вида:

REPORT  yuuk_test_select.

DATA: lt_mseg LIKE mseg OCCURS 1 WITH HEADER LINE,
      runtime_1 TYPE i,
      runtime_2 TYPE i,
      time_diff TYPE i.

FIELD-SYMBOLS: <fs> LIKE LINE OF lt_mseg.

SELECT * INTO TABLE lt_mseg
FROM mseg.

GET RUN TIME FIELD runtime_1.
LOOP AT lt_mseg.
  lt_mseg-bwart = '000'.
  MODIFY lt_mseg.
ENDLOOP.
GET RUN TIME FIELD runtime_2.
time_diff = runtime_2 - runtime_1.
WRITE: / time_diff.

GET RUN TIME FIELD runtime_1.
LOOP AT lt_mseg ASSIGNING <fs>.
  <fs>-bwart = '000'.
ENDLOOP.
GET RUN TIME FIELD runtime_2.
time_diff = runtime_2 - runtime_1.
WRITE: / time_diff.

Результат на экране, комментарии я так думаю излишние, разница в производительности даже не на лице  ;) в надцать раз практически, т.е.  192 580 миллисекунд против  12 172, кажется закрывают данный вопрос как нужно делать обновления внутренних таблиц.

PS: Данный пример так же вставлю в тему по оптимизации ABAP.

Dmitriy

#22
Собственно, ждемс, что скажет нам завтра г-н Паганель, лишь бы не перепутал Южную Америку с Австралией и Н.Зеландией, или как там у автора было... Нужно просто сгенерить диалог ведения, для красоты в табличку БД yxxx добавить неключевое поле поле status_text с расшифровкой статуса типа "загруженно с магазина + расчитано в SAP", сгенерить диалог ведения и не париться с INSERT в нее в своей программе, сориентировав ответственных за ведение статусов (то бишь нашей небольшой таблички) при помощи соответствующей спецификации/инструкции:
DATA: ls TYPE yxxx. "Тип нашей таблички с одной записью или без оной.
 SELECT SINGLE * INTO ls FROM yxxx.
 IF SY-SUBRC <> 0.
   ls-mandt = sy-mandt.
   ls-status = 'U'.
   INSERT INTO yxxx VALUES ls.
   COMMIT WORK AND WAIT.
 ENDIF.

А сразу же:
 SELECT xxx~fld_1 zzz~fld_2 yxxx~status INTO TABLE lt_int_file FROM xxx
   JOIN zzz ON (условия соединения)
   JOIN yxxx ON zzz~mandt = yxxx~mandt
   WHERE (разные ограничения)
   AND yxxx~status = 'нужный нам статус'.

Uukrul

Цитата: Dmitriy від Лютий 19, 2009, 09:16:39 ПП
Собственно, ждемс, что скажет нам завтра г-н Паганель, лишь бы не перепутал Южную Америку с Австралией и Н.Зеландией, или как там у автора было...
Ага, есть такое дело... но даже если он LOOP / ENDLOOP перепишет, это ему уже даст ускорение...  ;)

Dmitriy

Цитата: Uukrul від Лютий 19, 2009, 09:21:01 ПП
Ага, есть такое дело... но даже если он LOOP / ENDLOOP перепишет, это ему уже даст ускорение...  ;)
Да, результат выигрыша в быстродействии для большого к-ва записей впечатляет.
2 Паганель: завтра, как доберусь до системы, отпишу про возможности работы с ФМ - генерирующим диалог ведения таблицы БД. Здесь будет: http://sapforum.biz/index.php/board,29.0.html.

P.S. А руки все про FIELD-SYMBOLS так и не доходят написать, охота нормальный пример просто оттестить... ::)

SMF spam blocked by CleanTalk