SAP R/3 форум ABAP консультантов
Russian ABAP Developer's Club

Home - FAQ - Search - Memberlist - Usergroups - Profile - Log in to check your private messages - Register - Log in - English
Blogs - Weblogs News

вопрос от чайника: что быстрее работает?


Goto page 1, 2  Next
 
Post new topic   Reply to topic    Russian ABAP Developer's Club Forum Index -> ABAP
View previous topic :: View next topic  
Author Message
ablinka
Участник
Участник



Joined: 30 Sep 2008
Posts: 10

PostPosted: Tue Oct 28, 2008 3:31 am    Post subject: вопрос от чайника: что быстрее работает? Reply with quote

Что быстрее работает:
1. если сделать один select по всем нужным таблицам с помощью inner join и скинуть все данные во временную таблицу, а потом делать цикл по временной таблице.

2. Или же сделать вложенные select end select и внутри них обрабатывать данные?
Back to top
View user's profile Send private message
Armann
Модератор
Модератор



Joined: 01 Jan 2008
Posts: 422
Location: Moscow

PostPosted: Tue Oct 28, 2008 9:41 am    Post subject: Reply with quote

В общем случае предпочтительнее вариант с внутренней таблицей, но все зависит от конкретных условий - предполагаемого количества записей, количества таблиц, времени обработки и тд. Самое лучшее для вас - попробовать оба ваших варианта и еще третий: не пихать все в один запрос с join'ами, а попробовать разделить их на несколько, и посмотреть в SE30 сколько занимает времени обработка каждого варианта
Back to top
View user's profile Send private message Blog
ablinka
Участник
Участник



Joined: 30 Sep 2008
Posts: 10

PostPosted: Tue Oct 28, 2008 9:49 am    Post subject: Reply with quote

моя проблема в том , что оба варианта работают очень долго...я размещу код, если у вас будет время, посмотрите, плиз :

select MSEG~MATNR MSEG~MBLNR MSEG~BWART MSEG~WERKS MSEG~WAERS MSEG~LGORT MSEG~DMBTR MSEG~MENGE MSEG~ERFME MSEG~SHKZG MSEG~PRCTR MKPF~BUDAT
MARA~MATKL MARA~BRGEW MAKT~MAKTX
into corresponding fields of table osn_tbl
from MKPF inner join MSEG on MKPF~MBLNR = MSEG~MBLNR
inner join MARA on MARA~MATNR = MSEG~MATNR
inner join MAKT on MAKT~MATNR = MSEG~MATNR
where MKPF~BUDAT IN SBUDAT
and ( MSEG~BWART = 'Z01' or ( MSEG~BWART = 'Z02' and MSEG~SMBLN <> '' ) )
and MSEG~WERKS IN SWERKS
and MSEG~PRCTR in SLGORT
and MSEG~MATNR in SMATNR
and MARA~MATKL IN SMATKL.
.


второй вариант

SELECT * FROM MKPF WHERE BUDAT IN SBUDAT.

SELECT * FROM MSEG
WHERE MBLNR = MKPF-MBLNR AND ( BWART = 'Z01' or ( BWART = 'Z02' and smbln <> '' ) ) AND WERKS IN SWERKS and PRCTR IN slgort
.
SELECT * FROM mara WHERE matkl IN smatkl AND MATNR = MSEG-MATNR .
ENDSELECT.

IF SY-SUBRC = 0.
CLEAR YPP_VIPUSK.


if mseg-BWART = 'Z02'.
sign = -1.
else.
sign = 1.
endif.

YPP_VIPUSK-MATNR = MSEG-MATNR.
YPP_VIPUSK-ERFMG = MSEG-ERFMG * sign.

*вес
SELECT * FROM MARA WHERE MATNR = MSEG-MATNR.
YPP_VIPUSK-BRGEW = MARA-BRGEW.
ENDSELECT.

YPP_VIPUSK-BRGEW = YPP_VIPUSK-BRGEW * YPP_VIPUSK-ERFMG.

*наим
SELECT * FROM MAKT WHERE MATNR = MSEG-MATNR.
YPP_VIPUSK-MAKTX = MAKT-MAKTX.
ENDSELECT.

SELECT * FROM T001W WHERE WERKS = MSEG-WERKS.
VKORG_ = T001W-VKORG.
ENDSELECT.

*цена
SELECT * FROM A950 WHERE KAPPL = 'V' AND KSCHL = 'VKP0' AND VKORG = VKORG_
AND VTWEG = '01' AND WERKS = MSEG-WERKS
AND MATNR = YPP_VIPUSK-MATNR AND DATaB <= mkpf-BUDAT and DATBI >= mkpf-BUDAT.

SELECT * FROM KONP WHERE KNUMH = A950-KNUMH.

YPP_VIPUSK-KBETR = KONP-KBETR * sign.

ENDSELECT.

YPP_VIPUSK-DMBTR = YPP_VIPUSK-KBETR * YPP_VIPUSK-ERFMG.

ENDSELECT.
Back to top
View user's profile Send private message
Armann
Модератор
Модератор



Joined: 01 Jan 2008
Posts: 422
Location: Moscow

PostPosted: Tue Oct 28, 2008 10:04 am    Post subject: Reply with quote

Я к сожалению с MM особо не работал, так глядя на запрос сказать не могу, надо это проверять у вас в трассировщике. Но второй вариант с SELECT..ENDSELECT думаю можете однозначно выкинуть
Back to top
View user's profile Send private message Blog
vga
Мастер
Мастер


Age: 170
Joined: 04 Oct 2007
Posts: 1218
Location: Санкт-Петербург

PostPosted: Tue Oct 28, 2008 11:27 am    Post subject: Reply with quote

В системе должен быть индекс MSEG~M (Material documents for material ), попробуйте его использовать:
Code:
SELECT mseg~matnr
       mseg~mblnr
       mseg~bwart
       mseg~werks
       mseg~waers
       mseg~lgort
       mseg~dmbtr
       mseg~menge
       mseg~erfme
       mseg~shkzg
       mseg~prctr
       mkpf~budat
       mara~matkl
       mara~brgew
       makt~maktx
INTO CORRESPONDING FIELDS OF TABLE osn_tbl
FROM mseg
INNER JOIN mkpf ON mkpf~mblnr = mseg~mblnr
               AND mkpf~mjahr = mseg~mjahr
INNER JOIN mara ON mara~matnr = mseg~matnr
INNER JOIN makt ON makt~matnr = mseg~matnr
WHERE mseg~matnr IN smatnr
  AND mseg~werks IN swerks
  AND ( mseg~bwart = 'Z01'
    OR ( mseg~bwart = 'Z02' AND mseg~smbln <> '' ))
  AND mseg~prctr IN slgort
  AND mkpf~budat IN sbudat
  AND mara~matkl IN smatkl.
Back to top
View user's profile Send private message Blog Visit poster's website
author
Участник
Участник



Joined: 28 Oct 2008
Posts: 1

PostPosted: Tue Oct 28, 2008 1:27 pm    Post subject: Reply with quote

в первую очередь советую убрать "не равно":
Code:
AND mseg~smbln <> ''

а потом в цикле обработать его
Back to top
View user's profile Send private message
Удав
Гуру
Гуру


Age: 48
Joined: 25 Jan 2008
Posts: 580
Location: Москва

PostPosted: Tue Oct 28, 2008 3:54 pm    Post subject: Re: вопрос от чайника: что быстрее работает? Reply with quote

ablinka wrote:
Что быстрее работает:
1. если сделать один select по всем нужным таблицам с помощью inner join и скинуть все данные во временную таблицу, а потом делать цикл по временной таблице.

2. Или же сделать вложенные select end select и внутри них обрабатывать данные?


Почитайте об оптимизации запросов.

Вложенные SELECT ... ENDSELECT лучше сразу забыть - используйте вместо этого SELECT ... INTO TABLE, LOOP ... ENDLOOP.

При выборе inner join vs select по отдельным таблицам нужно учитывать следующие обстоятельства:

1.Если соединение идет с настроечными таблицами (имя таблицы T*), то join не нужен, т.к. настроечные таблицы в большинстве своем буферизируются на уровне Application server.
2.Если идет соединение с таблицами основных данных (MARA, MAKT), то вместо join лучше использовать select single + сортированную внутреннюю таблицу:
Code:
DATA: begin of gs_mara,
        matnr TYPE mara-matnr,
        matkl TYPE mara-matkl,
        maktx TYPE makt-maktx,
      end of gs_mara,
      gt_mara LIKE SORTED TABLE OF gs_mara WITH UNIQUE KEY matnr.

...
  LOOP AT gt_data ASSIGNING <fs_data>.
    PERFORM get_mara USING <fs_data>.
...
  ENDLOOP.
....
  FORM get_mara USING p_data LIKE gs_data.
    READ TABLE gt_mara INTO gs_mara WITH KEY matnr = p_data-matnr.
    IF sy-subrc <> 0.
      CLEAR gs_mara.
      gs_mara-matnr = p_data-matnr.
      SELECT SINGLE matkl
      INTO gs_mara-matkl
      FROM mara
      WHERE matnr = gs_mara-matnr.

      IF sy-subrc = 0.
        SELECT SINGLE maktx
        INTO gs_mara-maktx
        FROM makt
        WHERE matnr = gs_mara-matnr
          AND spras = sy-langu.
      ENDIF.
      INSERT gs_mara INTO TABLE gt_mara.
    ENDIF.
    MOVE-CORRESPONDING gs_mara TO p_data.
  ENDFORM.
  ....


3. Если поле из справочника участвует в ограничении значений, можно поступить 2-мя способами:
а) Если ограничение позволяет выбрать мало записей из правочника и является обязательным, то вначале нужно выбрать данные из справочника по условию во внутреннюю таблицу или RANGE, затем делать выборку по основной таблице
б) Если ограничение не является обязательным и с его помощью нельзя сильно ограничить выборку, то данные выбираются, как в п.2, но в цикле после заполнения полей из справочника удаляются данные, не соответствующие ограничению на экране выбора.

4.Если выборка должна быть из 2-х таблиц с переменными данными, и условие соединения включает в себя первичный ключ или содержится в каком-либо индексе, то лучше применять JOIN (как пример - таблицы MKPF, MSEG)

5. По возможности не используйте конструкции OR в условиях выборки

_________________
С уважением,
Удав.
Back to top
View user's profile Send private message
John Doe
Модератор
Модератор


Age: 46
Joined: 05 Nov 2007
Posts: 725
Location: КраснАдар

PostPosted: Tue Oct 28, 2008 4:09 pm    Post subject: Reply with quote

to Удав: Привет! А можешь ссылку на оригинал дать ?
Quote:
2.Если идет соединение с таблицами основных данных (MARA, MAKT), то вместо join лучше использовать select single + сортированную внутреннюю таблицу:
Back to top
View user's profile Send private message Blog
Удав
Гуру
Гуру


Age: 48
Joined: 25 Jan 2008
Posts: 580
Location: Москва

PostPosted: Tue Oct 28, 2008 7:11 pm    Post subject: Reply with quote

John Doe, это из личного опыта Smile

Отчеты по документам материала за месяц:

SELECT SINGLE MARA + SELECT SINGLE MAKT = 692 милисекунды на запись

SELECT SINGLE MARA join MAKT = 602 милисекунды на запись

Можно еще уменьшить время выборки
SELECT ... MARA FOR ALL ENTRIES join MAKT = 380 милисекунды

Но этот способ не очень красивый с точки зрения реализации, когда в рамках одной записи в основных данных есть несколько полей с номерами материалов, например в случае отчетов по перемещениям материала может быть задействовано не только поле MSEG-MATNR, но и MSEG-UMMAT.

Выделение из join MKPF+MSEG таблиц MARA и MAKT дало прирост производительности ~30%.
Возможно, причина еще и в том, что таблицы настройки, таблицы основных данных и таблицы переменных данных лежат в разных tablespace.

Во всех отчетах выборка из MARA+MAKT не превышает 3% от общего выполнения программы. В случае с select single - вообще 0,3% Wink

_________________
С уважением,
Удав.
Back to top
View user's profile Send private message
John Doe
Модератор
Модератор


Age: 46
Joined: 05 Nov 2007
Posts: 725
Location: КраснАдар

PostPosted: Wed Oct 29, 2008 12:05 am    Post subject: Reply with quote

ОК, понял, спасибо. Буду применять. Если все будет плохо - гневно отпишусь Laughing
Back to top
View user's profile Send private message Blog
ablinka
Участник
Участник



Joined: 30 Sep 2008
Posts: 10

PostPosted: Wed Oct 29, 2008 3:12 pm    Post subject: Reply with quote

спасибо большое всем! буду пробовать.
Back to top
View user's profile Send private message
fashionPunk
Участник
Участник



Joined: 07 Oct 2007
Posts: 17

PostPosted: Fri Mar 13, 2009 4:10 pm    Post subject: Re: вопрос от чайника: что быстрее работает? Reply with quote

ablinka wrote:
Что быстрее работает:
1. если сделать один select по всем нужным таблицам с помощью inner join и скинуть все данные во временную таблицу, а потом делать цикл по временной таблице.

2. Или же сделать вложенные select end select и внутри них обрабатывать данные?


Сделать ракурс БД с нужным join и из него делать селехт, работает очень быстро.
Back to top
View user's profile Send private message
Armann
Модератор
Модератор



Joined: 01 Jan 2008
Posts: 422
Location: Moscow

PostPosted: Fri Mar 13, 2009 4:36 pm    Post subject: Re: вопрос от чайника: что быстрее работает? Reply with quote

fashionPunk wrote:
Сделать ракурс БД с нужным join и из него делать селехт, работает очень быстро.

Вы уверены?
Насколько я помню - у вьюхи есть небольшое преимущество в скорости за счет того, что план запроса хранится в готовом виде, но кардинально это проблему скорости не решает. Тяжелый и большой запрос - он и есть большой и тяжелый, в каком бы виде он не выполнялся
Back to top
View user's profile Send private message Blog
fashionPunk
Участник
Участник



Joined: 07 Oct 2007
Posts: 17

PostPosted: Fri Mar 13, 2009 4:53 pm    Post subject: Re: вопрос от чайника: что быстрее работает? Reply with quote

Armann wrote:
fashionPunk wrote:
Сделать ракурс БД с нужным join и из него делать селехт, работает очень быстро.

Вы уверены?
Насколько я помню - у вьюхи есть небольшое преимущество в скорости за счет того, что план запроса хранится в готовом виде, но кардинально это проблему скорости не решает. Тяжелый и большой запрос - он и есть большой и тяжелый, в каком бы виде он не выполнялся


ну вот относительно недавно оптимизировал одну программу с join по 4 таблицам, сдлал на ракурсе, время выполнения существенно уменьшилось на процентов 20
Back to top
View user's profile Send private message
Armann
Модератор
Модератор



Joined: 01 Jan 2008
Posts: 422
Location: Moscow

PostPosted: Fri Mar 13, 2009 5:33 pm    Post subject: Re: вопрос от чайника: что быстрее работает? Reply with quote

fashionPunk wrote:
ну вот относительно недавно оптимизировал одну программу с join по 4 таблицам, сдлал на ракурсе, время выполнения существенно уменьшилось на процентов 20

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

2All. В MS SQL вроде как можно создавать индексы к вьюхам. Интересно, на Сап это какое нить влияние оказывает? Строится ли каким либо образом такой индекс, или 'не положено - значит неположено'?
Back to top
View user's profile Send private message Blog
Display posts from previous:   
Post new topic   Reply to topic    Russian ABAP Developer's Club Forum Index -> ABAP All times are GMT + 4 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


All product names are trademarks of their respective companies. SAPNET.RU websites are in no way affiliated with SAP AG.
SAP, SAP R/3, R/3 software, mySAP, ABAP, BAPI, xApps, SAP NetWeaver and any other are registered trademarks of SAP AG.
Every effort is made to ensure content integrity. Use information on this site at your own risk.