Оптимизация ABAP-а

Автор Uukrul, Травень 16, 2008, 11:39:58 ДП

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

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

Паганель

Цитата: Martha від Липень 30, 2009, 01:33:42 ПП
У нас есть таблица  t1 в которой помимо ключа, есть индекс по полям f1, f3,f6, f7.

Есть
select  *  from t1
where f7  = z7  and f1 = z1 and f6 = z6 and f3 = z3.

Есть ли разница в скорости работы в том, в какой последовательности перечислены поля в where, если в индексе они идут – см выше.


По моим наблюдениям (т.е. это ИМХО), разницы нет, порядок и количество влияет только на выбор индекса, т.е. если у вас есть два индекса с полями f1, f2, f3 и f1,f3 то выбор идет как раз по порядку следования полей......
Хотя может на это влияет еще и используемая БД......

Кстати вы смотрели какой индекс используется (st05)?

У вас какая то конкретная проблема? Может приведете код и какие у вас индексы?

Uukrul

Цитата: Паганель від Липень 29, 2009, 12:35:09 ПП
Пример, или подробнее можно?
Ну индекс желательно делать так... как на картинке, первое поле мандантик, так как при запросе
SELECT * FROM EQUI
WHERE MATNR = xxx AND
     SERNR = zzzz AND
     WERK = yyy.

Будет работать индекс, так как на уровень запроса пойдут так же данные манданта.

Uukrul

Цитата: Паганель від Липень 30, 2009, 01:44:37 ПП
Хотя может на это влияет еще и используемая БД......
Ну для оракла порядок важен... если его не соблюдать, то индексы просто не используются в таком случае...

Удав

Цитата: Uukrul  link=topic=174.msg4587#msg4587 date=1248950978
Ну для оракла порядок важен... если его не соблюдать, то индексы просто не используются в таком случае...
Это для какой версии Oracle?
Для 9-ки без разницы, в каком порядке идут поля в WHERE...
Оптимизатор подбирает один из индексов:
-с наибольшим количеством совпадающих с условием полей
-с полями, по которым селективность больше.

Uukrul

Цитата: Удав від Серпень 05, 2009, 11:39:06 ДП
Это для какой версии Oracle?
Для 9-ки без разницы, в каком порядке идут поля в WHERE...
У нас 10 с копейками, админы настаивают на соблюдении порядка следования индексов... хотя я тоже был уверен что оптимизатор типа умнее должен быть... в противном случае индекс почему-то не подхватывается.

Удав

Вот примеры:
SQL Statement                                                                   
                                                                               
SELECT                                                                         
  *                                                                             
FROM                                                                           
  mseg                                                                         
WHERE                                                                           
  bwart = :A1   and charg = :a2   and werks = :a3                               
                                                                               
Execution Plan                                                                 
                                                                               
SELECT STATEMENT ( Estimated Costs = 1 , Estimated #Rows = 1 )                 
                                                                               
     5  2 TABLE ACCESS BY INDEX ROWID MSEG                                     
          ( Estim. Costs = 1 , Estim. #Rows = 1 )                               
                                                                               
            1 INDEX SKIP SCAN MSEG~ZZ2                                         
              ( Estim. Costs = 3 , Estim. #Rows = 1 )                           
              Search Columns: 3                                                 

NONUNIQUE  Index   MSEG~ZZ2                     
                                                 
Column Name                     #Distinct       
MANDT                                          1
CHARG                                    193 201
WERKS                                         58
BWART                                         63


SELECT                                                                               
  *                                                                                 
FROM                                                                                 
  mseg                                                                               
WHERE                                                                               
  bwart = :A1   and werks = :a3                                                     
                                                                                     
Execution Plan                                                                       
SELECT STATEMENT ( Estimated Costs = 1 916 , Estimated #Rows = 3 700 )             
                                                                                     
     5  2 TABLE ACCESS BY INDEX ROWID MSEG                                           
          ( Estim. Costs = 1 916 , Estim. #Rows = 3 700 )                           
                                                                                     
            1 INDEX SKIP SCAN MSEG~M                                                 
              ( Estim. Costs = 17 536 , Estim. #Rows = 3 700 )                       
              Search Columns: 2           

NONUNIQUE  Index   MSEG~M                       
                                                 
Column Name                     #Distinct       
MANDT                                          1
MATNR                                     17 533
WERKS                                         58
LGORT                                        729
BWART                                         63
SOBKZ                                          3                                           

Удав

А вот что получается при добавлении условия с MANDT ;)
SELECT                                                                            
 *                                                                              
FROM                                                                              
 mseg                                                                            
WHERE                                                                            
 mandt = :A4   and werks = :a3   and bwart = :A1                                
                                                                                 
                                                                                 
Execution Plan                                                                    
SELECT STATEMENT ( Estimated Costs = 228 , Estimated #Rows = 3 700 )            
                                                                                 
    5  2 TABLE ACCESS BY INDEX ROWID MSEG                                        
         ( Estim. Costs = 228 , Estim. #Rows = 3 700 )                          
                                                                                 
           1 INDEX RANGE SCAN MSEG~ZZ5                                          
             ( Estim. Costs = 1 053 , Estim. #Rows = 3 700 )                    
             Search Columns: 3      

SELECT                                                                         
  *                                                                             
FROM                                                                           
  mseg                                                                         
WHERE                                                                           
  mandt = :A4   and bwart = :A1   and werks = :a3                               
                                                                               
                                                                               
Execution Plan                                                                 
SELECT STATEMENT ( Estimated Costs = 228 , Estimated #Rows = 3 700 )           
                                                                               
     5  2 TABLE ACCESS BY INDEX ROWID MSEG                                     
          ( Estim. Costs = 228 , Estim. #Rows = 3 700 )                         
                                                                               
            1 INDEX RANGE SCAN MSEG~ZZ5                                         
              ( Estim. Costs = 1 053 , Estim. #Rows = 3 700 )                   
              Search Columns: 3                                                 

NONUNIQUE  Index   MSEG~ZZ5                    
                                               
Column Name                     #Distinct      
MANDT                                          1
WERKS                                         58
LGORT                                        729
BWART                                         63
SOBKZ                                          3
                                           

Uukrul

SELECT                                                                          
 *                                                                            
FROM                                                                            
 mseg                                                                          
WHERE                                                                          
 bwart = :A1   and charg = :a2   and werks = :a3                              

Давай этот запрос со сменой порядка следования полей, т.е. количество полей тоже 3, но порядок разный.

Удав

С мандантом
SQL Statement                                                                 
                                                                               
SELECT                                                                         
  *                                                                           
FROM                                                                           
  mseg                                                                         
WHERE                                                                         
  mandt = :a01   and charg = :a2   and werks = :a3   and bwart = :a4           
                                                                               
Execution Plan                                                                 
SELECT STATEMENT ( Estimated Costs = 1 , Estimated #Rows = 1 )               
                                                                               
     5  2 TABLE ACCESS BY INDEX ROWID MSEG                                     
          ( Estim. Costs = 1 , Estim. #Rows = 1 )                             
                                                                               
            1 INDEX RANGE SCAN MSEG~ZZ2                                       
              ( Estim. Costs = 3 , Estim. #Rows = 1 )                         
              Search Columns: 4                                               

Без манданта
SQL Statement                                                                     
                                                                                 
SELECT                                                                           
  *                                                                               
FROM                                                                             
  mseg                                                                           
WHERE                                                                             
  werks = :a3   and charg = :a2   and bwart = :a4                                 
                                                                                 
Execution Plan                                                                   
SELECT STATEMENT ( Estimated Costs = 1 , Estimated #Rows = 1 )                   
                                                                                 
     5  2 TABLE ACCESS BY INDEX ROWID MSEG                                       
          ( Estim. Costs = 1 , Estim. #Rows = 1 )                                 
                                                                                 
            1 INDEX SKIP SCAN MSEG~ZZ2                                           
              ( Estim. Costs = 3 , Estim. #Rows = 1 )                             
              Search Columns: 3                                                   

Uukrul

Ну судя по всему не влияет... надо будет посмотреть у себя. А то может зря поверил на слово админам ::)

Martha

Цитата: Паганель від Липень 30, 2009, 01:44:37 ПП
По моим наблюдениям (т.е. это ИМХО), разницы нет, порядок и количество влияет только на выбор индекса, т.е. если у вас есть два индекса с полями f1, f2, f3 и f1,f3 то выбор идет как раз по порядку следования полей......
Хотя может на это влияет еще и используемая БД......

Кстати вы смотрели какой индекс используется (st05)?

У вас какая то конкретная проблема? Может приведете код и какие у вас индексы?

как посмотреть какие индексы используются? в st05  я вижу только запрос

tav_48

Цитата: Martha від Серпень 07, 2009, 08:35:54 ДП
как посмотреть какие индексы используются? в st05  я вижу только запрос

http://sy-subrc.blogspot.com/2008/08/sql.html

Паганель

Цитата: Martha від Серпень 07, 2009, 08:35:54 ДП
как посмотреть какие индексы используются? в st05  я вижу только запрос

Кнопка "Explain"

Паганель

#113
Вот мы тут обсуждали, делились опытом, пришли к определенным выводам.......
Самая популярная тема в молодежи  ;)

Только вот сел тут одну прожку делать .... и вижу что не работает как надо .....


Есть выборка

 SELECT SUM( dmbtr ) AS dmbtr bukrs zuonr shkzg hkont blart
 APPENDING CORRESPONDING FIELDS OF TABLE gt_bsis
   FROM bsis
 WHERE
     bukrs IN so_bukrs      AND
     hkont =  '0070300800'  AND
     zuonr IN sa_lifnr      AND
     blart = 'RV' AND
     budat IN so_budat AND
     shkzg = 'H'
     GROUP BY bukrs hkont zuonr  budat shkzg  blart.


У bsis есть три индекса:
Первичный, включающий такие поля:
MANDT   
BUKRS   
HKONT   
AUGDT   
AUGBL   
ZUONR
GJAHR   
BELNR   
BUZEI   

1
MANDT
BUKRS
BELNR
GJAHR
BUZEI

и
"ZAN"
BUKRS
ZUONR
BEWAR

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

Но сие чудо, т.е. SAP чего-то использует последний индекс "ZAN".

Может кто то объяснит мне чего же так? А то моя вера в SAP пошатнулась .....  :)


Паганель

Проблему решил, убрал из выборки поле "Присвоение" (zuonr), выборка срабатывает мнговенно, предидущая - минут 20 и больше и падала по таймауту ......

Выводы? .....

Uukrul

Цитата: Паганель від Серпень 07, 2009, 05:57:04 ПП

 SELECT SUM( dmbtr ) AS dmbtr bukrs zuonr shkzg hkont blart
 APPENDING CORRESPONDING FIELDS OF TABLE gt_bsis
   FROM bsis
 WHERE
     bukrs IN so_bukrs      AND
     hkont =  '0070300800'  AND
     zuonr IN sa_lifnr      AND
     blart = 'RV' AND
     budat IN so_budat AND
     shkzg = 'H'
     GROUP BY bukrs hkont zuonr  budat shkzg  blart.


У bsis есть три индекса:
Первичный, включающий такие поля:
MANDT   
BUKRS   
HKONT   
AUGDT   
AUGBL   
ZUONR
GJAHR   
BELNR   
BUZEI   
А с чего ты взял что первичный должен использоваться? У тебя тут совпадает только  BUKRS и HKONT, дальше все мимо кассы так как значения AUGDT и AUGBL не заданы вообще, то до ZUONR оно вообще не доходит, так что правильно оно его не берет. Ну если ты конечно уверен что нужен именно этот индекс, тогда можно через %_HINTS его задать, если правильно синтаксис помню. Но я бы так не делал, оптимизатору виднее.

Uukrul

Цитата: Паганель від Серпень 07, 2009, 06:06:09 ПП
Проблему решил, убрал из выборки поле "Присвоение" (zuonr), выборка срабатывает мнговенно, предидущая - минут 20 и больше и падала по таймауту ......

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

MANDT   
BUKRS   
HKONT   
AUGDT   
AUGBL   
ZUONR
GJAHR   
BELNR   
BUZEI   

А в условии выборки, ты их зада в таком порядке
BUKRS   
HKONT   
<пропущено AUGDT>
<пропущено AUGBL>
ZUONR
<Остальное не важно>

Система при анализе дошла до того что поля AUGDT и AUGBL не заданы, поэтому индекс использоваться не может, а то что ты задал ZUONR, ей по барабану так как по дереву она до него дойти минуя вышестоящие и не определенные AUGDT и AUGBL, никак не может. Кстати твой следующий индекс "ZAN" и подхаватывается потому что идут поля которые есть в индексе и между ними нет пропусков:
BUKRS
ZUONR
<Последние поля не важны BEWAR>, так вот если бы в индексе было вот это BEWAR и оно стояло между BUKRS и ZUONR, но ты его не задавал бы как в предыдущем AUGDT и AUGBL, то у тебя бы и индекс "ZAN" вряд ли бы использовался, получил бы фулскан таблицы.

Поэтому когда ты убрал ZUONR, оно сравнило этих два индекса, в первом есть два поля, во втором только одно.. само собой искать надо по первому.

Про B-дерево для начала тут: http://ru.wikipedia.org/wiki/B-дерево , хотя там тема большая и вариаций на его тему много.

Паганель

Спасибо, в принципе понятно, немного теории тут точно не помешает.....

Цитата: Uukrul  від Серпень 07, 2009, 09:21:28 ПП
Кстати твой следующий индекс "ZAN" и подхаватывается потому что идут поля которые есть в индексе и между ними нет пропусков:
BUKRS
ZUONR
<Последние поля не важны BEWAR>, так вот если бы в индексе было вот это BEWAR и оно стояло между BUKRS и ZUONR, но ты его не задавал бы как в предыдущем AUGDT и AUGBL, то у тебя бы и индекс "ZAN" вряд ли бы использовался, получил бы фулскан таблицы.

Поэтому когда ты убрал ZUONR, оно сравнило этих два индекса, в первом есть два поля, во втором только одно.. само собой искать надо по первому.

Про B-дерево для начала тут: http://ru.wikipedia.org/wiki/B-дерево , хотя там тема большая и вариаций на его тему много.

Правда, так и не понял, почему все-таки при выборе индекса, рассматривалось поле zuonr, по моему ситуация в обеих случаях аналогична, в первом индексе есть два поля которые иду подряд, во втором тоже 2 поля, которые идут подряд..... далее идут поля которые присутствуют в условиях выбора но не входят в индекс..... И в первом и во втором случае - одно и тоже .... интересно, как повела бы себя система, если бы было наоборот - в первом индексе было бы поле zuonr, а во втором hkont, что система выбрала бы опять второй? не логично ..... у меня подозрение что тут играет роль еще и то что, поле zuonr больше по длине, естественно, и индекс тоже больше .... хотя первый индекс по количеству полей и может данных, больше ....

Хм, что ли почитать по теории баз данных? Что посоветуешь?  :)

Да точно, сразу после изучения BC400 (если честно и его не читал), надо начинающим абаперам, сразу же читать BC490 (Оптимизация)....

Uukrul

Цитата: Паганель від Серпень 07, 2009, 10:13:41 ПП
Правда, так и не понял, почему все-таки при выборе индекса, рассматривалось поле zuonr, по моему ситуация в обеих случаях аналогична, в первом индексе есть два поля которые иду подряд, во втором тоже 2 поля, которые идут подряд..... далее идут поля которые
Ну что тебе сказать... так как слова B-Tree тебе ничего не говорят то как бы сложно объяснить почему оно так берет индексы, я вот попытался но похоже не получилось. Так что проехали.

Паганель

Ок, может на досуге почитаю про твои бе-три  :)

Uukrul

Цитата: Паганель від Серпень 07, 2009, 11:43:27 ПП
Ок, может на досуге почитаю про твои бе-три  :)
Да оно только зря время потратишь.. .читать надо что-то про то как строяться индексные файлы в базах данных и далее по нарастающей... а так оно все равно ничего не ясно будет.

Паганель

Цитата: Uukrul  link=topic=174.msg4658#msg4658 date=1249679631
Да оно только зря время потратишь.. .читать надо что-то про то как строяться индексные файлы в базах данных и далее по нарастающей... а так оно все равно ничего не ясно будет.

Может и точно, зачем в такие дебри залазить  :)

Паганель

Опять я с теми же вопросами, делаю ту же выборку, только поменял № счета и вид документа, и снова выборка не отрабатывает за 20 мин.


    SELECT SUM( dmbtr ) AS dmbtr bukrs zuonr shkzg hkont blart
  APPENDING CORRESPONDING FIELDS OF TABLE gt_bsis
    FROM bsis
  WHERE
      bukrs IN so_bukrs      AND
      hkont = '0063109900' AND
      blart = 'WA'     AND
      budat IN so_budat         AND
      shkzg = 'H'
      GROUP BY bukrs hkont zuonr  budat shkzg  blart.


Уже все мозги сломал, где что не так?

Uukrul

Цитата: Паганель від Серпень 10, 2009, 01:04:41 ПП
Опять я с теми же вопросами, делаю ту же выборку, только поменял № счета и вид документа, и снова выборка не отрабатывает за 20 мин.
Ну план запроса однако давай... какие индексы потянулись, какие есть?

Паганель

#124
Не получается просмотреть трасировку, выборка падает по таймату, и в трассировке не видно данных про выборку с bsis..... очень странно .....

Самое странное, стоит поменять номер счета на такой же как в предидущем примере, и все работает очень быстро........ разница в данных только в том что для счета 0063109900 не заполняется поле zuonr

Так работает быстро (но не правильно)

 SELECT SUM( dmbtr ) AS dmbtr bukrs zuonr shkzg hkont blart
 APPENDING CORRESPONDING FIELDS OF TABLE gt_bsis
   FROM bsis
 WHERE
     bukrs IN so_bukrs      AND
     hkont ='0070300800'    AND    
     blart = 'WA'           AND
     budat IN so_budat        AND
     shkzg = 'H'
     GROUP BY bukrs hkont zuonr  budat shkzg  blart.


А так сильно долго работает:

 SELECT SUM( dmbtr ) AS dmbtr bukrs zuonr shkzg hkont blart
 APPENDING CORRESPONDING FIELDS OF TABLE gt_bsis
   FROM bsis
 WHERE
     bukrs IN so_bukrs      AND
     hkont ='0063109900' AND
     blart = 'WA'           AND
     budat IN so_budat        AND
     shkzg = 'H'
     GROUP BY bukrs hkont zuonr  budat shkzg  blart.


Для первого запроса - трасировка на рис. ниже

SMF spam blocked by CleanTalk