+ Sapforum.Biz » Инструменты » ABAP - Инструментальные средства » SE38 - ABAP Редактор » Технологии написания программ на ABAP (Модератор: Dmitriy)Тема:
|- Как ускорить запрос?




Автор Тема: Как ускорить запрос?  (Прочитано 2598 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн shirakz

  • Newbie
  • *
  • Сообщений: 19
  • Reputation Power: 0
  • shirakz has no influence.
  • YearsYearsYears
Как ускорить запрос?
« : Март 15, 2017, 06:24:45 am »
Доброе утро!

В одной программе почти последовательно вызываются 2 запроса по одной и той же таблице JVSO1 (25 млн записей). Но первый запрос выполняется за 1.1 секунду а второй за 724 секунды (12 минут). Смотрел через ST05.
Единственное существенное отличие это наличие во 2 запросе фильтра по полю "REFFIDOC", ну ещё в 1 запросе есть сортировка, а во втором нет. И во втором запросе фильтр по "RACCT" более широкий, зато по "DOCTY" более узкий.

1) SELECT  WHERE "RCLNT"= '300' AND "RLDNR"= '4A' AND "RBUKRS"= 'KZ01' AND "RACCT"= 'A2680009' AND "DOCTY" IN ( 'RE' , 'KR' , 'RM' , 'RT' ) AND "BUDAT" BETWEEN '20170313' AND '20170313'  ORDER BY "RTCUR","DOCNR","RCNTR","RRECIN","DOCTY","BUDAT","CPUDT","REFFIDOC"

2) SELECT  WHERE "RCLNT"= '300' AND "RLDNR"= '4A' AND "RBUKRS"= 'KZ01' AND ("RACCT"= 'A2680009' OR "RACCT"= 'A2680011' OR "RACCT"= 'A2680012' OR "RACCT"= 'A2680013' OR "RACCT"= 'A2680014' OR "RACCT"= 'A2680015' OR "RACCT"= 'A2680016' OR "RACCT"= 'A2680017' ) AND "DOCTY"= 'P3' AND "BUDAT"= '20170313' AND "REFFIDOC" IN ( '1900006493' , '5110000038' , '1000000014' , '1000000013' )

1 запрос выбирает только 3 записи, а 2 - 24 записи.

Как ускорить запрос?
« Последнее редактирование: Март 15, 2017, 06:31:07 am от shirakz »

Оффлайн Uukrul

  • SAP ECC 6.0 Ehp(*)
  • Administrator
  • Epic Member
  • *****
  • Сообщений: 3 674
  • Reputation Power: 2
  • Uukrul barely matters.Uukrul barely matters.
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • Sapforum.BIZ
Re: Как ускорить запрос?
« Ответ #1 : Март 15, 2017, 10:43:58 am »
Ну в качестве рекламы купите You are not allowed to view links. Register or Login, так как, для того чтобы понять как работает запрос, писать его примеры не очень актуально, более правильным является просмотр плана запроса, там более будет наглядно почему запросы работают по разному, для этого цитата из книги (раздел про ST05):
Цитировать
Вторая полезная функция этого отчёта - просмотр плана выполнения запроса, т. е. определение индексов, используемых операцией для выбора данных. Для просмотра плана запроса нужно установить курсор на операцию OPEN и нажать кнопку F9 – Explain for an SQL Statement.
Так что присылайте планы запросов, будем смотреть.

Оффлайн shirakz

  • Newbie
  • *
  • Сообщений: 19
  • Reputation Power: 0
  • shirakz has no influence.
  • YearsYearsYears
Re: Как ускорить запрос?
« Ответ #2 : Март 15, 2017, 12:12:05 pm »
Когда выбираю "For Recorded Statement" то выходит сообщение:
"There is no execution plan for the statement of the selected trace record".
Поэтому выбираю "For Statement to be entered"
и там получаю:

Код: You are not allowed to view links. Register or Login
SELECT
  *
FROM
  JVSO1
WHERE
  RLDNR = '4A' AND RBUKRS = 'KZ01' AND ( RACCT = 'A2680009' OR RACCT = 'A2680011' OR RACCT =
  'A2680012' OR RACCT = 'A2680013' OR RACCT = 'A2680014' OR RACCT = 'A2680015' OR RACCT =
  'A2680016' OR RACCT = 'A2680017' ) AND DOCTY = 'P3' AND BUDAT = '20170313' AND REFFIDOC IN (
  '1900006493' , '5110000038' , '1000000014' , '1000000013' )


Execution Plan

Sql_id: 2azdmq5xvrxy1



 SELECT STATEMENT ( Estimated Costs = 29,664 , Estimated #Rows = 1 )

        2 TABLE ACCESS BY INDEX ROWID JVSO1
          ( Estim. Costs = 29,663 , Estim. #Rows = 1 )
          Estim. CPU-Costs = 1,614,141,029 Estim. IO-Costs = 29,650
          Filter Predicates

            1 INDEX SKIP SCAN JVSO1~REP
              ( Estim. Costs = 5,811 , Estim. #Rows = 3,134,988 )
              Search Columns: 2
              Estim. CPU-Costs = 172,495,101 Estim. IO-Costs = 5,810
              Access Predicates Filter Predicates

А если сделать фильтр по REFFIDOC с одним значением, то получим:

Код: You are not allowed to view links. Register or Login
SQL Statement

SELECT
  *
FROM
  JVSO1
WHERE
  RLDNR = '4A' AND RBUKRS = 'KZ01' AND ( RACCT = 'A2680009' OR RACCT = 'A2680011' OR RACCT =
  'A2680012' OR RACCT = 'A2680013' OR RACCT = 'A2680014' OR RACCT = 'A2680015' OR RACCT =
  'A2680016' OR RACCT = 'A2680017' ) AND DOCTY = 'P3' AND BUDAT = '20170313' AND REFFIDOC =
  '1900006493'


Execution Plan

Sql_id: 3kd1c2dcgar0m



 SELECT STATEMENT ( Estimated Costs = 204 , Estimated #Rows = 1 )

        2 TABLE ACCESS BY INDEX ROWID JVSO1
          ( Estim. Costs = 204 , Estim. #Rows = 1 )
          Estim. CPU-Costs = 1,502,141 Estim. IO-Costs = 204
          Filter Predicates

            1 INDEX SKIP SCAN JVSO1~ZJV
              ( Estim. Costs = 200 , Estim. #Rows = 122 )
              Search Columns: 2
              Estim. CPU-Costs = 1,432,017 Estim. IO-Costs = 200
              Access Predicates Filter Predicates

Я так понимаю Estimated Costs = 204 это быстро? В 1 варианте у меня Estimated Costs = 29,664.
А что значит "1 INDEX SKIP SCAN" индекс есть, но он пропущен - не использовался?

Вот сами индексы:

Код: You are not allowed to view links. Register or Login
NONUNIQUE  Index     JVSO1~ZJV

Column Name                     #Distinct

RYEAR                                           10
REFFIDOC                                    88,417
REFFIDLN                                       999
RBUKRS                                           2
RJVNAM                                           5

Код: You are not allowed to view links. Register or Login
NONUNIQUE  Index     JVSO1~REP

Column Name                     #Distinct

RCLNT                                            1
RLDNR                                            4
RRCTY                                            1
RVERS                                            1
RYEAR                                           10
RBUKRS                                           2
RJVNAM                                           5
POPER                                           12

Может мне надо создать индекс? Или так неправильно?

Оффлайн shirakz

  • Newbie
  • *
  • Сообщений: 19
  • Reputation Power: 0
  • shirakz has no influence.
  • YearsYearsYears
Re: Как ускорить запрос?
« Ответ #3 : Март 15, 2017, 12:17:41 pm »
Статью читал, но там не вся она есть, я так понимаю. Книгу покупать - это долгая история )

Что-то не вижу OPEN:
Код: You are not allowed to view links. Register or Login
09:39:49.153 3,369 0 R_ST05_TRACE_MAIN COMMIT WORK ON CONNECTION 0 0 R/3 NK11014522 300 DIA
09:39:54.348 24,156 3 ZRFI036_KZ_RECLASS_7VAT_ACC JVSO1 SELECT  WHERE "RCLNT"= '300' AND "RLDNR"= '4A' AND "RBUKRS"= 'KZ01' AND "RACCT"= 'A2680009' AND "DOCTY" IN ( 'RE' , 'KR' , 'RM' 204 684 R/3 NK11014522 300 DIA
09:39:54.373 2,588 2 ZRFI036_KZ_RECLASS_7VAT_ACC BKPF SELECT  WHERE "MANDT"= '300' AND "BUKRS"= 'KZ01' AND "BELNR" IN ( '1900006493' , '5100049180' ) AND "BUDAT"= '20170313' 19 1,250 R/3 NK11014522 300 DIA
09:39:54.376 10,221 1 ZRFI036_KZ_RECLASS_7VAT_ACC RBKP SELECT  WHERE "MANDT"= '300' AND "BUKRS"= 'KZ01' AND "BELNR" IN ( '1900006493' , '5110000038' ) AND "BUDAT"= '20170313' 202 2,096 R/3 NK11014522 300 DIA
09:39:54.386 51,062 2 ZRFI036_KZ_RECLASS_7VAT_ACC BKPF SELECT  WHERE "MANDT"= '300' AND "BUKRS"= 'KZ01' AND "BLART"= 'P3' AND "BUDAT"= '20170313' AND "XBLNR" IN ( '1900006493' , '5100 209 984 R/3 NK11014522 300 DIA
09:39:54.437 72,101,822 24 ZRFI036_KZ_RECLASS_7VAT_ACC JVSO1 SELECT  WHERE "RCLNT"= '300' AND "REFFIDOC" IN ( '1900006493' , '5110000038' , '1000000014' , '1000000013' ) AND "RLDNR"= '4A' A 89 492 R/3 NK11014522 300 DIA
09:41:06.540 455 0 SAPLSDNT DDNTT SELECT  WHERE TABNAME = '' 111 1 R/3 NK11014522 300 DIA

Оффлайн shirakz

  • Newbie
  • *
  • Сообщений: 19
  • Reputation Power: 0
  • shirakz has no influence.
  • YearsYearsYears
Re: Как ускорить запрос?
« Ответ #4 : Март 15, 2017, 02:34:27 pm »
Вот кстати план 1го селекта (Estimated Costs = 559):

Код: You are not allowed to view links. Register or Login
SELECT
  *
FROM
  JVSO1
WHERE
  "RCLNT"= '300' AND "RLDNR"= '4A' AND "RBUKRS"= 'KZ01' AND "RACCT"= 'A2680009' AND "DOCTY" IN (
  'RE' , 'KR' , 'RM' , 'RT' ) AND "BUDAT" BETWEEN '20170313' AND '20170313'
ORDER BY
  "RTCUR","DOCNR","RCNTR","RRECIN","DOCTY","BUDAT","CPUDT","REFFIDOC"


Execution Plan

Sql_id: 0ysmp21fk76ad



 SELECT STATEMENT ( Estimated Costs = 559 , Estimated #Rows = 1 )

        3 SORT ORDER BY
          ( Estim. Costs = 559 , Estim. #Rows = 1 )
          Estim. CPU-Costs = 262,842,091 Estim. IO-Costs = 557

            2 TABLE ACCESS BY INDEX ROWID JVSO1
              ( Estim. Costs = 558 , Estim. #Rows = 1 )
              Estim. CPU-Costs = 140,889,091 Estim. IO-Costs = 557
              Filter Predicates

                1 INDEX SKIP SCAN JVSO1~1
                  ( Estim. Costs = 147 , Estim. #Rows = 14,003 )
                  Search Columns: 4
                  Estim. CPU-Costs = 132,275,402 Estim. IO-Costs = 146
                  Access Predicates Filter Predicates

Индекс 1 такой:

Код: You are not allowed to view links. Register or Login
NONUNIQUE  Index     JVSO1~1

Column Name                     #Distinct

RCLNT                                            1
RBUKRS                                           2
RLDNR                                            4
RJVNAM                                           5
REGROU                                           3
RACCT                                        1,791
RYEAR                                           10
RVERS                                            1
RRCTY                                            1

Оффлайн shirakz

  • Newbie
  • *
  • Сообщений: 19
  • Reputation Power: 0
  • shirakz has no influence.
  • YearsYearsYears
Re: Как ускорить запрос?
« Ответ #5 : Март 15, 2017, 03:21:56 pm »
Проблема в том, что в селекте одновременно присутствуют два фильтра с OR в полях RACCT и REFFIDOC. Видимо произошло перемножение в выборке. Поэтому в плане 2-го селекта выбралось более 3 млн записей:
Код: You are not allowed to view links. Register or Login
1 INDEX SKIP SCAN JVSO1~REP
              ( Estim. Costs = 5,811 , Estim. #Rows = 3,134,988 )

Так как по логике моей программы у меня всегда счетов ровно 8. То я просто сделаю 8 селектов подобного рода (Estimated Costs = 557):

Код: You are not allowed to view links. Register or Login
SELECT
  *
FROM
  JVSO1
WHERE
  "RLDNR"= '4A' AND "RBUKRS"= 'KZ01' AND ( "RACCT" = 'A2680017' ) AND "DOCTY" = 'P3' AND "BUDAT"
  BETWEEN '20170313'   AND '20170313' AND ( REFFIDOC =   '1900006493' OR REFFIDOC = '5110000038' OR
  REFFIDOC =   '1000000014' OR REFFIDOC = '1000000013' )


Execution Plan

Sql_id: 3bt1y4rm1ns7s



 SELECT STATEMENT ( Estimated Costs = 557 , Estimated #Rows = 1 )

        2 TABLE ACCESS BY INDEX ROWID JVSO1
          ( Estim. Costs = 557 , Estim. #Rows = 1 )
          Estim. CPU-Costs = 10,236,629 Estim. IO-Costs = 557
          Filter Predicates

            1 INDEX SKIP SCAN JVSO1~1
              ( Estim. Costs = 146 , Estim. #Rows = 14,003 )
              Search Columns: 3
              Estim. CPU-Costs = 1,623,122 Estim. IO-Costs = 146
              Access Predicates Filter Predicates

И получится Estimated Costs = 557 * 8 = 4456
Лучше чем Estimated Costs = 29,664.

Верная логика?

P.S. Пока ускорение почти в 7 раз :)
« Последнее редактирование: Март 15, 2017, 03:23:51 pm от shirakz »

Оффлайн shirakz

  • Newbie
  • *
  • Сообщений: 19
  • Reputation Power: 0
  • shirakz has no influence.
  • YearsYearsYears
Re: Как ускорить запрос?
« Ответ #6 : Март 15, 2017, 03:48:06 pm »
Добился Estimated Costs = 806 с одним запросом!
С помощью  "RACCT" = 'A2680009' OR "RACCT" BETWEEN 'A2680011' AND  'A2680017'.
Но не уверен можно ли так делать. И #Rows = 2 почему-то - всегда было 1.

Код: You are not allowed to view links. Register or Login
SELECT
  *
FROM
  JVSO1
WHERE
  "RBUKRS"= 'KZ01' AND "RLDNR"= '4A'  AND ( "RACCT" = 'A2680009' OR "RACCT" BETWEEN 'A2680011' AND
  'A2680017' ) AND "DOCTY" = 'P3' AND "BUDAT" BETWEEN '20170313'   AND '20170313' AND "REFFIDOC" IN
  ( '1900006493' , '5110000038' , '1000000014' , '1000000013' )


Execution Plan

Sql_id: bc58fh3q6y06x



 SELECT STATEMENT ( Estimated Costs = 806 , Estimated #Rows = 2 )

        5 CONCATENATION

            2 TABLE ACCESS BY INDEX ROWID JVSO1
              ( Estim. Costs = 557 , Estim. #Rows = 1 )
              Estim. CPU-Costs = 10,236,629 Estim. IO-Costs = 557
              Filter Predicates

                1 INDEX SKIP SCAN JVSO1~1
                  ( Estim. Costs = 146 , Estim. #Rows = 14,003 )
                  Search Columns: 3
                  Estim. CPU-Costs = 1,623,122 Estim. IO-Costs = 146
                  Access Predicates Filter Predicates

            4 TABLE ACCESS BY INDEX ROWID JVSO1
              ( Estim. Costs = 248 , Estim. #Rows = 1 )
              Estim. CPU-Costs = 3,372,184 Estim. IO-Costs = 248
              Filter Predicates

                3 INDEX SKIP SCAN JVSO1~1
                  ( Estim. Costs = 146 , Estim. #Rows = 3,501 )
                  Search Columns: 3
                  Estim. CPU-Costs = 1,218,452 Estim. IO-Costs = 146
                  Access Predicates Filter Predicates

P.S. Пока ускорение почти в 37 (!) раз :)

Оффлайн Uukrul

  • SAP ECC 6.0 Ehp(*)
  • Administrator
  • Epic Member
  • *****
  • Сообщений: 3 674
  • Reputation Power: 2
  • Uukrul barely matters.Uukrul barely matters.
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • Sapforum.BIZ
Re: Как ускорить запрос?
« Ответ #7 : Март 15, 2017, 08:16:37 pm »
Поздравляю, так сказать опыт полученный путем экспериментов, он точно не забывается. Что касается плана запроса и где его смотреть. Система развивается и сейчас это выглядит так, находим в анализе свой запрос, рисунок ST05-1.png, выделяем его в таблице и нажимаем кнопку "Display Individual Records" перейдем в детальный анализ запроса, рисунок ST05-2.png и уже тут можем видеть как выполнялся запрос. Становимся на строку OPEN и нажимаем кнопку просмотра плана запроса. Переходим в просмотр плана запроса, рисунок ST05-3.png, мне проще смотреть план в текстовом виде, поэтому я нажимаю перейти к текстовому представлению, кнопка "EXPALIN Display as Text", рисунок ST05-4.png и получаем текстовое представление.  В вашем случае таки похоже что действительно #Rows = 3,134,988, т.е. выбиралось больше 3 млн. записей.


Оффлайн Stepan

  • Newbie
  • *
  • Сообщений: 5
  • Reputation Power: 0
  • Stepan has no influence.
  • YearsYearsYearsYears
Re: Как ускорить запрос?
« Ответ #8 : Март 16, 2017, 06:47:18 am »
В качестве общего дополнения к работе запросов и оптимизатора базы.
1 - попросите базис обновить статистику для таблицы. Именно на ней основывается оптимизатор базы при построении плана, а в системе SAP этот сбор статистики хоть и запланирован стандартным базисным заданием, но довольно специфичен и зависит от многих условий. Статистика может быть неактуальна.
2 - попробуйте использовать хинты в запросе для указания нужного вам индекса. При этом невзирая на бОльший кост результат будет лучше :)
3 - попробуйте подставить хинт SUBSTITUTE_VALUES

Оффлайн shirakz

  • Newbie
  • *
  • Сообщений: 19
  • Reputation Power: 0
  • shirakz has no influence.
  • YearsYearsYears
Re: Как ускорить запрос?
« Ответ #9 : Март 16, 2017, 08:04:41 am »
Видимо Estimated costs неверно оценивается :(
Переделал запрос в программе на BETWEEN и получил всё равно 708 секунд. Вот план (в нём кстати Estimated Costs = 6,747 а не 29 тысяч - но секунд-то всё равно более 700):

Код: You are not allowed to view links. Register or Login
SELECT
  "RTCUR","RACCT","RCNTR","RRECIN","TSL","HSL","KSL","SGTXT","BUDAT","CPUDT","REFFIDOC"
FROM
  "JVSO1"
WHERE
  "RCLNT"=:A0 AND "RLDNR"=:A1 AND "RBUKRS"=:A2 AND ("RACCT"=:A3 OR "RACCT" BETWEEN :A4 AND :A5) AND
  "DOCTY"=:A6 AND "BUDAT"=:A7 AND "REFFIDOC" IN (:A8,:A9,:A10,:A11)


Execution Plan

Sql_id: cw19tvg6tma77



 Existing Plan Hash Values with Parse Timestamps:

 2026709298 15.MAR.2017 13:57:44 v$sql_plan
 2026709298 15.MAR.2017 13:57:44 dba_hist_sql_plan

 SELECT STATEMENT ( Estimated Costs = 6,747 , Estimated #Rows = 1 )

        2 TABLE ACCESS BY INDEX ROWID JVSO1
          ( Estim. Costs = 6,746 , Estim. #Rows = 1 )
          Estim. CPU-Costs = 247,145,479 Estim. IO-Costs = 6,744
          Filter Predicates

            1 INDEX RANGE SCAN JVSO1~1
              ( Estim. Costs = 6,465 , Estim. #Rows = 9,584 )
              Search Columns: 3
              Estim. CPU-Costs = 241,450,417 Estim. IO-Costs = 6,463
              Access Predicates Filter Predicates

а вот подробный план в текстовом виде:

Код: You are not allowed to view links. Register or Login
SQL Statement
----------------------------------------------------------------------------------------------------------------------
SELECT
  "RTCUR","RACCT","RCNTR","RRECIN","TSL","HSL","KSL","SGTXT","BUDAT","CPUDT","REFFIDOC"
FROM
  "JVSO1"
WHERE
  "RCLNT"=:A0 AND "RLDNR"=:A1 AND "RBUKRS"=:A2 AND ("RACCT"=:A3 OR "RACCT" BETWEEN :A4 AND :A5) AND
  "DOCTY"=:A6 AND "BUDAT"=:A7 AND "REFFIDOC" IN (:A8,:A9,:A10,:A11)


Execution Plan

----------------------------------------------------------------------------------------------------------------------
System: T1E
Plan hash value: 2026709298

---------------------------------------------------------------------------------------
| Id  | Operation                   | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |         |     1 |   117 |  6747   (1)| 00:05:58 |
|*  1 |  TABLE ACCESS BY INDEX ROWID| JVSO1   |     1 |   117 |  6746   (1)| 00:05:58 |
|*  2 |   INDEX RANGE SCAN          | JVSO1~1 |  9584 |       |  6465   (1)| 00:05:43 |
---------------------------------------------------------------------------------------

Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------

   1 - SEL$1 / JVSO1@SEL$1
   2 - SEL$1 / JVSO1@SEL$1

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("BUDAT"=:A7 AND "DOCTY"=:A6 AND ("REFFIDOC"=:A8 OR
              "REFFIDOC"=:A9 OR "REFFIDOC"=:A10 OR "REFFIDOC"=:A11))
   2 - access("RCLNT"=:A0 AND "RBUKRS"=:A2 AND "RLDNR"=:A1)
       filter("RACCT">=:A4 AND "RACCT"<=:A5 OR "RACCT"=:A3)

Column Projection Information (identified by operation id):
-----------------------------------------------------------

   1 - "RTCUR"[VARCHAR2,15], "RACCT"[VARCHAR2,30], "RCNTR"[VARCHAR2,30],
       "RRECIN"[VARCHAR2,6], "TSL"[NUMBER,22], "HSL"[NUMBER,22], "KSL"[NUMBER,22],
       "SGTXT"[VARCHAR2,150], "BUDAT"[VARCHAR2,24], "CPUDT"[VARCHAR2,24],
       "REFFIDOC"[VARCHAR2,30]
   2 - "JVSO1".ROWID[ROWID,10], "RACCT"[VARCHAR2,30]

Оффлайн Uukrul

  • SAP ECC 6.0 Ehp(*)
  • Administrator
  • Epic Member
  • *****
  • Сообщений: 3 674
  • Reputation Power: 2
  • Uukrul barely matters.Uukrul barely matters.
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • Sapforum.BIZ
Re: Как ускорить запрос?
« Ответ #10 : Март 16, 2017, 03:36:27 pm »
You are not allowed to view links. Register or Login
2 - попробуйте использовать хинты в запросе для указания нужного вам индекса. При этом невзирая на бОльший кост результат будет
А вот это честно не надо...  и если честно в большинстве случае за хинты отрывают руки. Так что должна быть очень серьезная причина работать с хинтом. Хинт фактически отключает оптимизатор и запрос работает только по указанному индексу, а это значит, что DBA по факту не сможет влиять на оптимизацию доступов к базе инструментарием СУБД. В данном случае, вот ускорили в 37 раз, если правильно запомнил, так вот это уже и есть ответом на то нужны хинты или нет.

Оффлайн Uukrul

  • SAP ECC 6.0 Ehp(*)
  • Administrator
  • Epic Member
  • *****
  • Сообщений: 3 674
  • Reputation Power: 2
  • Uukrul barely matters.Uukrul barely matters.
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • Sapforum.BIZ
Re: Как ускорить запрос?
« Ответ #11 : Март 16, 2017, 03:53:47 pm »
You are not allowed to view links. Register or Login
Видимо Estimated costs неверно оценивается :(
Ну статистику собрать, но из запроса видно что система выбирает первый индек JVSO1~1 Кстати, через DB05 можно посмотреть количество значений записей для разных полей таблицы. Принцип так такой что позволяет оценить имеет ли смысл использовать поле для ограничения. Ну например если поле содержит только 2 значения, то включение поля в ключ и выборку часто не имеет смысла, так как это очень широкое ограничение. В DB05 указываете таблицу и до 5 полей для анализа.

Оффлайн shirakz

  • Newbie
  • *
  • Сообщений: 19
  • Reputation Power: 0
  • shirakz has no influence.
  • YearsYearsYears
Re: Как ускорить запрос?
« Ответ #12 : Март 17, 2017, 10:29:49 am »
Сделал 8 селектов (на каждый счёт - один селект) вместо одного. Типа:

SELECT  WHERE "RCLNT"= '300' AND "RLDNR"= '4A' AND "RBUKRS"= 'KZ01' AND "RACCT"= 'A2680011' AND "DOCTY"= 'P3' AND "BUDAT"= '2017...

Получил сегодня с утра на НЕкэшированной базе время выполнения программы 5 секунд вместо изначальных 726 секунд!
Итого ускорение в 145 раз!

Всё-таки 2 range в одном селекте это много - происходит перемножение. И, например, у меня получилось, что из 25 млн записей сперва отбирается 3 млн, а потом из них всего 24 записи. А в этих 8 запросах отбирается изначально всего по 14 тысяч записей.

Код: You are not allowed to view links. Register or Login
SELECT
  "RTCUR","RACCT","RCNTR","RRECIN","TSL","HSL","KSL","SGTXT","BUDAT","CPUDT","REFFIDOC"
FROM
  "JVSO1"
WHERE
  "RCLNT"=:A0 AND "RLDNR"=:A1 AND "RBUKRS"=:A2 AND "RACCT"=:A3 AND "DOCTY"=:A4 AND "BUDAT"=:A5 AND
  "REFFIDOC" IN (:A6,:A7,:A8,:A9)


Execution Plan

Sql_id: 0x60xdsv4ws2p



 Existing Plan Hash Values with Parse Timestamps:

 3466282620 16.MAR.2017 10:46:57 v$sql_plan
 3466282620 16.MAR.2017 10:46:57 dba_hist_sql_plan

 SELECT STATEMENT ( Estimated Costs = 568 , Estimated #Rows = 1 )

        2 TABLE ACCESS BY INDEX ROWID JVSO1
          ( Estim. Costs = 568 , Estim. #Rows = 1 )
          Estim. CPU-Costs = 135,975,375 Estim. IO-Costs = 567
          Filter Predicates

            1 INDEX SKIP SCAN JVSO1~1
              ( Estim. Costs = 147 , Estim. #Rows = 14,069 )
              Search Columns: 4
              Estim. CPU-Costs = 127,768,882 Estim. IO-Costs = 146
              Access Predicates Filter Predicates

Причём время 2 запроса из 8 - почти 0,9 секунд, а потом меньше. Вот цифры в микросекундах:
895,163
623,980
658,616
537,345
359,067
175,943
342,895
Происходит уменьшение времени видимо из-за кэширования. Хотя последний запрос 0,34 секунды.

Код: You are not allowed to view links. Register or Login
SQL Statement
----------------------------------------------------------------------------------------------------------------------
SELECT
  "RTCUR","RACCT","RCNTR","RRECIN","TSL","HSL","KSL","SGTXT","BUDAT","CPUDT","REFFIDOC"
FROM
  "JVSO1"
WHERE
  "RCLNT"=:A0 AND "RLDNR"=:A1 AND "RBUKRS"=:A2 AND "RACCT"=:A3 AND "DOCTY"=:A4 AND "BUDAT"=:A5 AND
  "REFFIDOC" IN (:A6,:A7,:A8,:A9)


Execution Plan

----------------------------------------------------------------------------------------------------------------------
System: T1E
Plan hash value: 3466282620

---------------------------------------------------------------------------------------
| Id  | Operation                   | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |         |     1 |   117 |   568   (1)| 00:00:31 |
|*  1 |  TABLE ACCESS BY INDEX ROWID| JVSO1   |     1 |   117 |   568   (1)| 00:00:31 |
|*  2 |   INDEX SKIP SCAN           | JVSO1~1 | 14069 |       |   147   (1)| 00:00:08 |
---------------------------------------------------------------------------------------

Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------

   1 - SEL$1 / JVSO1@SEL$1
   2 - SEL$1 / JVSO1@SEL$1

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("BUDAT"=:A5 AND "DOCTY"=:A4 AND ("REFFIDOC"=:A6 OR
              "REFFIDOC"=:A7 OR "REFFIDOC"=:A8 OR "REFFIDOC"=:A9))
   2 - access("RCLNT"=:A0 AND "RBUKRS"=:A2 AND "RLDNR"=:A1 AND "RACCT"=:A3)
       filter("RACCT"=:A3)

Column Projection Information (identified by operation id):
-----------------------------------------------------------

   1 - "RTCUR"[VARCHAR2,15], "RACCT"[VARCHAR2,30], "RCNTR"[VARCHAR2,30],
       "RRECIN"[VARCHAR2,6], "TSL"[NUMBER,22], "HSL"[NUMBER,22], "KSL"[NUMBER,22],
       "SGTXT"[VARCHAR2,150], "BUDAT"[VARCHAR2,24], "CPUDT"[VARCHAR2,24],
       "REFFIDOC"[VARCHAR2,30]
   2 - "JVSO1".ROWID[ROWID,10], "RACCT"[VARCHAR2,30]

ИТОГО, остановлюсь на 5 секундах, думаю быстрее не получится ))

Оффлайн shirakz

  • Newbie
  • *
  • Сообщений: 19
  • Reputation Power: 0
  • shirakz has no influence.
  • YearsYearsYears
Re: Как ускорить запрос?
« Ответ #13 : Март 17, 2017, 10:32:14 am »
Вообще надо освежить память, насчёт того, как работает SQL. С этими знаниями, думаю, не будет таких проблем. Может кто знает, что почитать?

Оффлайн shirakz

  • Newbie
  • *
  • Сообщений: 19
  • Reputation Power: 0
  • shirakz has no influence.
  • YearsYearsYears
Re: Как ускорить запрос?
« Ответ #14 : Март 17, 2017, 01:47:26 pm »
You are not allowed to view links. Register or Login
Ну статистику собрать
а что Вы имели в виду под этим?

Оффлайн Uukrul

  • SAP ECC 6.0 Ehp(*)
  • Administrator
  • Epic Member
  • *****
  • Сообщений: 3 674
  • Reputation Power: 2
  • Uukrul barely matters.Uukrul barely matters.
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • Sapforum.BIZ
Re: Как ускорить запрос?
« Ответ #15 : Март 17, 2017, 06:29:55 pm »
You are not allowed to view links. Register or Login
ИТОГО, остановлюсь на 5 секундах, думаю быстрее не получится ))
Думаю быстрее никто и не заметит что стало  8) как говорится в любом деле главное вовремя остановиться. А по поводу сбора статистики, у администратора базы данных вашей системы есть операция обновления статистики. Обычно оно автоматом раз в пару недель обновляет такие данные для индексов таблиц, чтобы система находила более оптимальный индекс. В общем виде статистика это число 1 деленное на количество уникальных записей в таблице. Поэтому исходя из этой формулы чем меньше число тем лучше индекс. Самое минимальное число это в случае уникального или первичного индекса получается. Ну а дальше уже пошли варианты.