Posted: Tue Aug 07, 2012 7:51 am Post subject: Долгое время выполнения запроса
Добрый день! Имеется два запроса, первый выполняется мгновенно, второй минуты 3. Разница в них только в одном условии
mkpf~budat < budat-low и mkpf~budat in budat
SELECT mseg~bukrs mseg~werks mseg~matnr makt~maktx mseg~shkzg sum( mseg~menge ) as MENGE from mseg join mkpf on "Выбор данных на нижнюю дату
mseg~MBLNR = MKPF~MBLNR and mseg~MJAHR = MKPF~MJAHR
join makt on mseg~MATNR = makt~MATNR into CORRESPONDING FIELDS OF TABLE lt_mseg1 where
mseg~bukrs = BUKRS and mseg~werks in WERKS and mseg~matnr in MATNR and mkpf~budat < budat-low
and mseg~CHARG <> ''
GROUP BY mseg~bukrs mseg~werks mseg~matnr makt~maktx mseg~shkzg.
SELECT mseg~bukrs mseg~werks mseg~matnr makt~maktx mseg~shkzg sum( mseg~menge ) as MENGE from mseg join mkpf on "Выбор данных в диапазоне даты
mseg~MBLNR = mkpf~MBLNR and mseg~MJAHR = mkpf~MJAHR
join makt on mseg~MATNR = makt~MATNR into CORRESPONDING FIELDS OF TABLE lt_mseg2 where
mseg~bukrs = BUKRS and mseg~werks in WERKS and mseg~matnr in MATNR and mkpf~budat in budat
and mseg~CHARG <> ''
GROUP BY mseg~bukrs mseg~werks mseg~matnr makt~maktx mseg~shkzg.
При условии mkpf~budat < budat-high запрос также выполняется мгновенно. Но при выборе в диапазоне, надолго задумывается... Что то можно с этим сделать?
SELECT mseg~bukrs mseg~werks mseg~matnr makt~maktx mseg~shkzg sum( mseg~menge ) as MENGE from mseg join mkpf on "Выбор данных в диапазоне даты
mseg~MBLNR = mkpf~MBLNR and mseg~MJAHR = mkpf~MJAHR
join makt on mseg~MATNR = makt~MATNR into CORRESPONDING FIELDS OF TABLE lt_mseg2 where
( mseg~bukrs = BUKRS and mseg~werks in WERKS and mseg~matnr in MATNR and mseg~CHARG <> '' ) and mkpf~budat > budat-low and mkpf~budat <= budat-high
GROUP BY mseg~bukrs mseg~werks mseg~matnr makt~maktx mseg~shkzg.
Пришлось добавить в программу один цикл, и данный селект
SELECT mseg~bukrs mseg~werks mseg~matnr mseg~shkzg sum( mseg~menge ) as MENGE from mseg join mkpf on "Выбор данных в диапазоне даты
mseg~MBLNR = mkpf~MBLNR and mseg~MJAHR = mkpf~MJAHR
into CORRESPONDING FIELDS OF TABLE lt_mseg2 where
mseg~bukrs = BUKRS and mseg~werks in WERKS and mseg~matnr in MATNR and mkpf~budat > budat-low and mkpf~budat <= budat-high and mseg~CHARG <> ''
GROUP BY mseg~bukrs mseg~werks mseg~matnr mseg~shkzg
%_HINTS MSSQLNT '&SUBSTITUTE VALUES&'.
Опять стал грузиться несколько минут. Вообще не пойму ,что еще можно сделать, почему если используется диапазон то он так себя ведет.. ведь при условиях </ > выборка происходит мгновенно
Age: 48 Joined: 25 Jan 2008 Posts: 580 Location: Москва
Posted: Fri Aug 10, 2012 4:42 pm Post subject:
1.Потрассируйте запрос с помощью ST05 и выложите план запроса.
2.Зачем Вам sum и group by? Это дополнительная нагрузка на БД. _________________ С уважением,
Удав.
Last edited by Удав on Fri Aug 10, 2012 4:43 pm; edited 1 time in total
1.Потрассируйте запрос с помощью ST05 и выложите план запроса.
2.Зачем Вам sum и group by? Это дополнительная нагрузка на БД.
1. Трассировку сделаю в понедельник.
2. Необходимо определить сколько материала пришло, сколько ушло. При выполнении запроса, сразу получаются требуемые данные. Если делать через Loop то будет гораздо медленнее. Сума и группировка выполняется и в похожих запросах (не по диапазону) при этом они выполняются сразу.
Без агрегатной функции SUM и group by время выполнения запроса не меняется.
Может как то сам запрос еще можно изменить?
Можете описать как протрассировать запрос через ST05 или ссылку дать на описание, желательно на русском
Last edited by Tomatos on Sun Aug 12, 2012 12:43 pm; edited 1 time in total
а данные-то те же самые выбираются в обоих случаях? я имею в виду результат одинаков?
Первый запрос выбирает данные меньше нижней даты в диапазоне
Второй запрос выбирает данные в диапазоне
Третий запрос выбирает данные меньше верхней даты в диапазоне
Все строится по одним и тем же таблицам (запросы в программе следуют один за другим) при этом первый и третий отрабатываются моментально, но второй задумывает систему минут на 5. Все параметры выборки\группировки одинаковы, отличие же только в условии с датой.
Age: 48 Joined: 25 Jan 2008 Posts: 580 Location: Москва
Posted: Mon Aug 13, 2012 1:22 pm Post subject:
Tomatos wrote:
Можете описать как протрассировать запрос через ST05 или ссылку дать на описание, желательно на русском
Так там ничего сложного:
1. Запускаете свой отчет, заполняете экран выбора
2. В новом режиме запускаете ST05, нажимаете кнопку "Activate trace"
3. Запускаете отчет на выполнение.
4. По окончанию работы отчета выключаете трассировку с помощью кнопки "Dectivate trace"/
5. Смотрите результат трассировки с помощью кнопки "Display trace", при этом можно фильтровать трассировку по отдельным таблицам.
План запроса можно посмотреть по кнопке "Explain" _________________ С уважением,
Удав.
Вот результат при выполнении запроса
=========== INPUT ===============================
SELECT T_00."BUKRS" AS c,T_00."WERKS" AS c,T_00."MATNR" AS c,T_00."SHKZG" AS c,
SUM( T_00."MENGE" ) "MENGE"
FROM "MSEG" T_00 INNER
JOIN "MKPF" T_01 ON T_01."MANDT" = 555 AND T_00."MBLNR" = T_01."MBLNR"
AND
T_00."MJAHR" = T_01."MJAHR"
WHERE T_00."MANDT" = 555 AND T_00."BUKRS" = 12 AND T_00."WERKS" = 1203 AND
T_00."MATNR" =
41008649 AND T_01."BUDAT" > '01.01.2012' AND T_01."BUDAT" <=
'14.08.2012' AND T_00."CHARG" <>
'' AND T_00."BWART" <> '342'
GROUP BY T_00."BUKRS",T_00."WERKS",T_00."MATNR",T_00."SHKZG"
/* R3:YMM_REPORT_LIVE_MATER:207
T:MSEG 33441888103*/
/*Dynamic SQL statement -- no cursor, upto 0, conn. 0:1*/
=========== OUTPUT ==============================
SELECT T_00."BUKRS" AS c,T_00."WERKS" AS c,T_00."MATNR" AS c,T_00."SHKZG" AS c,
SUM( T_00."MENGE" ) "MENGE"
FROM "MSEG" T_00 INNER
JOIN "MKPF" T_01 ON T_01."MANDT" = 555 AND T_00."MBLNR" = T_01."MBLNR" AND
T_00."MJAHR" = T_01."MJAHR"
WHERE T_00."MANDT" = 555 AND T_00."BUKRS" = 12 AND T_00."WERKS" = 1203 AND
T_00."MATNR" = 41008649 AND T_01."BUDAT" > '01.01.2012' AND T_01."BUDAT" <=
'14.08.2012' AND T_00."CHARG" <>
'' AND T_00."BWART" <> '342'
GROUP BY T_00."BUKRS",T_00."WERKS",T_00."MATNR",T_00."SHKZG"
/* R3:YMM_REPORT_LIVE_MATER:207 T:MSEG 33441888103*/
/*Dynamic SQL statement -- no cursor, upto 0, conn. 0:1*/
SELECT
|--Stream Aggregate(GROUP BY:([T_00].[BUKRS], [T_00].[WERKS], [T_00].[MATNR], [T_00].[SHKZG]) DEFINE:([Expr1004]=SUM([RPR].[rpr].[MSEG].[MENGE] as [T_00].[MENGE])))
|--Nested Loops(Inner Join, WHERE:([RPR].[rpr].[MSEG].[MBLNR] as [T_00].[MBLNR]=[RPR].[rpr].[MKPF].[MBLNR] as [T_01].[MBLNR] AND [RPR].[rpr].[MSEG].[MJAHR] as [T_00].[MJAHR]=[RPR].[rpr].[MKPF].[MJAHR] as [T_01].[MJAHR]))
|--Sort(ORDER BY:([T_00].[BUKRS] ASC, [T_00].[WERKS] ASC, [T_00].[MATNR] ASC, [T_00].[SHKZG] ASC))
| |--Filter(WHERE:(CONVERT_IMPLICIT(int,[RPR].[rpr].[MSEG].[BUKRS] as [T_00].[BUKRS],0)=(12) AND ([RPR].[rpr].[MSEG].[CHARG] as [T_00].[CHARG]<'' OR [RPR].[rpr].[MSEG].[CHARG] as [T_00].[CHARG]>'')))
| |--Nested Loops(Inner Join, OUTER REFERENCES:([T_00].[MANDT], [T_00].[MBLNR], [T_00].[MJAHR], [T_00].[ZEILE], [Expr1011]) OPTIMIZED WITH UNORDERED PREFETCH)
| |--Index Scan(OBJECT:([RPR].[rpr].[MSEG].[MSEG~M] AS [T_00]), WHERE:(CONVERT_IMPLICIT(int,[RPR].[rpr].[MSEG].[MANDT] as [T_00].[MANDT],0)=(555) AND CONVERT_IMPLICIT(int,[RPR].[rpr].[MSEG].[WERKS] as [T_00].[WERKS],0)=(1203) AND CONVERT_IMPLICIT(int,[RPR].[rpr].[MSEG].[MATNR] as [T_00].[MATNR],0)=(41008649) AND ([RPR].[rpr].[MSEG].[BWART] as [T_00].[BWART]<'342' OR [RPR].[rpr].[MSEG].[BWART] as [T_00].[BWART]>'342')))
| |--Clustered Index Seek(OBJECT:([RPR].[rpr].[MSEG].[MSEG~0] AS [T_00]), SEEK:([T_00].[MANDT]=[RPR].[rpr].[MSEG].[MANDT] as [T_00].[MANDT] AND [T_00].[MBLNR]=[RPR].[rpr].[MSEG].[MBLNR] as [T_00].[MBLNR] AND [T_00].[MJAHR]=[RPR].[rpr].[MSEG].[MJAHR] as [T_00].[MJAHR] AND [T_00].[ZEILE]=[RPR].[rpr].[MSEG].[ZEILE] as [T_00].[ZEILE]) LOOKUP ORDERED FORWARD)
|--Table Spool
|--Index Scan(OBJECT:([RPR].[rpr].[MKPF].[MKPF~BUD] AS [T_01]), WHERE:([RPR].[rpr].[MKPF].[BUDAT] as [T_01].[BUDAT]>'01.01.2012' AND [RPR].[rpr].[MKPF].[BUDAT] as [T_01].[BUDAT]<='14.08.2012' AND CONVERT_IMPLICIT(int,[RPR].[rpr].[MKPF].[MANDT] as [T_01].[MANDT],0)=(555)))
SELECT T_00."BUKRS" AS c,T_00."WERKS" AS c,T_00."MATNR" AS c,T_02."MAKTX" AS c,
T_00."SHKZG" AS c,SUM( T_00."MENGE" ) "MENGE"
FROM "MSEG" T_00 INNER
JOIN "MKPF" T_01 ON T_01."MANDT" = @P0 AND T_00."MBLNR" = T_01."MBLNR" AND
T_00."MJAHR" = T_01."MJAHR" INNER
JOIN "MAKT" T_02 ON T_02."MANDT" = @P1 AND T_00."MATNR" = T_02."MATNR"
WHERE T_00."MANDT" = @P2 AND T_00."BUKRS" = @P3 AND T_00."WERKS" = @P4
AND T_00."MATNR" = @P5 AND T_01."BUDAT" < @P6 AND T_00."CHARG" <> @P7 AND
T_00."BWART" <> @P8
GROUP BY T_00."BUKRS",T_00."WERKS",T_00."MATNR",T_02."MAKTX",T_00."SHKZG"
/* R3:YMM_REPORT_LIVE_MATER:134 T:MSEG 33344188103*/
/*Dynamic SQL statement -- no cursor, upto 0, conn. 0:1*/
SELECT
|--Stream Aggregate(GROUP BY:([T_00].[SHKZG], [T_02].[MAKTX]) DEFINE:([Expr1006]=SUM([RPR].[rpr].[MSEG].[MENGE] as [T_00].[MENGE]), [T_00].[BUKRS]=ANY([RPR].[rpr].[MSEG].[BUKRS] as [T_00].[BUKRS]), [T_00].[WERKS]=ANY([RPR].[rpr].[MSEG].[WERKS] as [T_00].[WERKS]), [T_00].[MATNR]=ANY([RPR].[rpr].[MSEG].[MATNR] as [T_00].[MATNR])))
|--Sort(ORDER BY:([T_00].[SHKZG] ASC, [T_02].[MAKTX] ASC))
|--Nested Loops(Inner Join, OUTER REFERENCES:([T_00].[MBLNR], [T_00].[MJAHR], [Expr1009]) OPTIMIZED WITH UNORDERED PREFETCH)
|--Nested Loops(Inner Join)
| |--Clustered Index Seek(OBJECT:([RPR].[rpr].[MAKT].[MAKT~0] AS [T_02]), SEEK:([T_02].[MANDT]=[@P1] AND [T_02].[MATNR]=[@P5]) ORDERED FORWARD)
| |--Filter(WHERE:([RPR].[rpr].[MSEG].[BUKRS] as [T_00].[BUKRS]=[@P3] AND ([RPR].[rpr].[MSEG].[CHARG] as [T_00].[CHARG]<[@P7] OR [RPR].[rpr].[MSEG].[CHARG] as [T_00].[CHARG]>[@P7])))
| |--Nested Loops(Inner Join, OUTER REFERENCES:([T_00].[MANDT], [T_00].[MBLNR], [T_00].[MJAHR], [T_00].[ZEILE], [Expr1008]) OPTIMIZED WITH UNORDERED PREFETCH)
| |--Index Seek(OBJECT:([RPR].[rpr].[MSEG].[MSEG~M] AS [T_00]), SEEK:([T_00].[MANDT]=[@P2] AND [T_00].[MATNR]=[@P5] AND [T_00].[WERKS]=[@P4]), WHERE:([RPR].[rpr].[MSEG].[BWART] as [T_00].[BWART]<[@P8] OR [RPR].[rpr].[MSEG].[BWART] as [T_00].[BWART]>[@P8]) ORDERED FORWARD)
| |--Clustered Index Seek(OBJECT:([RPR].[rpr].[MSEG].[MSEG~0] AS [T_00]), SEEK:([T_00].[MANDT]=[RPR].[rpr].[MSEG].[MANDT] as [T_00].[MANDT] AND [T_00].[MBLNR]=[RPR].[rpr].[MSEG].[MBLNR] as [T_00].[MBLNR] AND [T_00].[MJAHR]=[RPR].[rpr].[MSEG].[MJAHR] as [T_00].[MJAHR] AND [T_00].[ZEILE]=[RPR].[rpr].[MSEG].[ZEILE] as [T_00].[ZEILE]) LOOKUP ORDERED FORWARD)
|--Clustered Index Seek(OBJECT:([RPR].[rpr].[MKPF].[MKPF~0] AS [T_01]), SEEK:([T_01].[MANDT]=[@P0] AND [T_01].[MBLNR]=[RPR].[rpr].[MSEG].[MBLNR] as [T_00].[MBLNR] AND [T_01].[MJAHR]=[RPR].[rpr].[MSEG].[MJAHR] as [T_00].[MJAHR]), WHERE:([RPR].[rpr].[MKPF].[BUDAT] as [T_01].[BUDAT]<[@P6]) ORDERED FORWARD)
Получается, предыдущий запрос строится по всей таблице MKPF без связи с MSEG, поэтому выполняется долго.
Age: 48 Joined: 25 Jan 2008 Posts: 580 Location: Москва
Posted: Tue Aug 14, 2012 9:48 am Post subject:
Tomatos wrote:
Первый запрос выбирает данные меньше нижней даты в диапазоне
Второй запрос выбирает данные в диапазоне
Третий запрос выбирает данные меньше верхней даты в диапазоне
Сдается мне, что в MS SQL свои особенности работы с диапазонами - в ORACLE оператор BETWEEN отрабатывает быстрее, чем > или <.
Попробуйте вместо 3-х запросов сделать один - без группировки с условием "меньше верхней даты в диапазоне". Условие по датам проверяйте внутри SELECT .. ENDSELECT и в зависимости от него заполняйте 3 таблицы.
ЗЫ: А зачем вообще нужен 3-й запрос?
Вычисление остатков на конец определяется как остатки на начало + обороты _________________ С уважением,
Удав.
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.