15.05.2013 15:27
PavelGS
 
Добрый день,
Есть задача выбрать продажи за несколько периодов для отправки их в другую БД.
Написал запрос, выбирает то что нужно. Но работает по 10 часов :(
Подскажите может я что то не так делаю.
Код:
 SELECT /*+ FIRST_ROWS(10) */
    C.ARTICLE,
       -- Продажи
       nvl((SELECT 
            SUM((CASE WHEN F.SALEOP=3 THEN (-1)*F.SALEQ ELSE F.SALEQ END)) AS SALEQ
            FROM SUPERMAG.FFMAPREP F  
            WHERE
            F.ARTICLE=C.ARTICLE 
            AND F.SALEOP in (1,3) 
            AND  F.RECTYPE=1 
            and  F.SALEDATE>=(select  TO_DATE(Add_Months(last_day(sysdate),-2)+1,'DD.MM.YY') from dual)
            AND  F.SALEDATE<=(select  TO_DATE(Add_Months(last_day(sysdate),-1),'DD.MM.YY') from dual)
            AND (F.SALELOCATIONFROM = SL.ID OR F.SALELOCATIONTO = SL.ID)
            ),0) SALEQ,
       nvl((SELECT 
            SUM((CASE WHEN F.SALEOP=3 THEN (-1)*F.SALESUM ELSE F.SALESUM END)) AS SALESUM
            FROM SUPERMAG.FFMAPREP F  
            WHERE
            F.ARTICLE=C.ARTICLE 
            AND F.SALEOP in (1,3) 
            AND  F.RECTYPE=1 
            and  F.SALEDATE>=(select  TO_DATE(Add_Months(last_day(sysdate),-2)+1,'DD.MM.YY') from dual)
            AND  F.SALEDATE<=(select  TO_DATE(Add_Months(last_day(sysdate),-1),'DD.MM.YY') from dual)
            AND (F.SALELOCATIONFROM = SL.ID OR F.SALELOCATIONTO = SL.ID)
            ),0) SALESUM,
            nvl((SELECT 
            SUM((CASE WHEN F.SALEOP=3 THEN (-1)*(F.SALESUM-F.PRIMECOST) ELSE (F.SALESUM-F.PRIMECOST) END)) AS DOXOD
            FROM SUPERMAG.FFMAPREP F  
            WHERE
            F.ARTICLE=C.ARTICLE 
            AND F.SALEOP in (1,3) 
            AND  F.RECTYPE=1 
            and  F.SALEDATE>=(select  TO_DATE(Add_Months(last_day(sysdate),-2)+1,'DD.MM.YY') from dual)
            AND  F.SALEDATE<=(select  TO_DATE(Add_Months(last_day(sysdate),-1),'DD.MM.YY') from dual)
            AND (F.SALELOCATIONFROM = SL.ID OR F.SALELOCATIONTO = SL.ID)
            ),0) DOXOD,
             (select price from SUPERMAG.smprices p where p.pricetype=1 and p.storeloc=13 and p.article=c.article) as price,
             SL.ID as mx,
             1 as period,
                 
     (case when ( 
     select 
         count(*)
     from 
            -- матрицы
            SUPERMAG.SMASSORTMATRIXLOC ML, SUPERMAG.SMCARDMATRIX M,
            --контракты
            SUPERMAG.SMDOCUMENTS D1, SUPERMAG.SMCONTRACTLOCATIONS L1, SUPERMAG.SMSPEC S1, SUPERMAG.SMContracts SC1
     where 
            -- матрицы
            ML.IDMATRIX=M.IDMATRIX 
            AND ML.STORELOC=SL.ID 
            AND M.ARTICLE=C.ARTICLE 
            AND SL.ID = ML.STORELOC 
            AND M.ARTICLE=C.ARTICLE
            --контракты
            AND D1.ID = S1.DOCID 
            AND D1.DOCTYPE = S1.DOCTYPE
            AND D1.DOCTYPE ='CO' 
            AND S1.ARTICLE = C.ARTICLE
            AND SC1.ID=D1.ID 
            AND SC1.DOCTYPE=D1.DOCTYPE
            AND SC1.BEGINSAT<=SYSDATE 
            AND ((SC1.ENDSAT>=SYSDATE) OR (SC1.ENDSAT IS Null)) 
            AND D1.DOCSTATE=2
     )>0 then 1 else 0 END) AS inMatrix
FROM
    SUPERMAG.smcard c,  
    SUPERMAG.SMSTORELOCATIONS SL
WHERE
     C.ACCEPTED =1
    -- Только магазины
    AND SL.ACCEPTED = 1
    AND SL.IDCLASS= 1
    AND SL.LOCTYPE = 4
    -- /Только магазины
15.05.2013 15:40
Troll
 
Для начала бы определиться, кто и куда это фетчит. Хинт стоит, но если фетчится сразу все, как в sql+, то лучше его убрать. Case там совсем не нужен. Это из практики убогого MS SQL. Decode попробуйте.
15.05.2013 16:22
PavelGS
 
Цитата:
Troll Для начала бы определиться, кто и куда это фетчит. Хинт стоит, но если фетчится сразу все, как в sql+, то лучше его убрать. Case там совсем не нужен. Это из практики убогого MS SQL. Decode попробуйте.
Без него то же самое
15.05.2013 16:27
whitewizard
 
а у меня этот скрипт быстро отрабатывает
15.05.2013 16:42
Troll
 
Цитата:
PavelGS Без него то же самое
вы умеете создавать впечатление, что ответ на вопрос нужен мне, а не вам
Цитата:
whitewizard а у меня этот скрипт быстро отрабатывает
от количества данных и проца зависит
15.05.2013 16:52
PavelGS
 
Цитата:
whitewizard а у меня этот скрипт быстро отрабатывает
В БД 20 Магазинов и 100 000 карточек базе 6 лет, 25 000 чеков в день
Подскажи те примерное время и Ваш объем данных в БД
15.05.2013 22:11
vdm
 
Погадаю.

Если оптимизатор не сотворит что-то умное, то с виду эта конструкция будет на вашей базе крутить миллионы не самых легких подзапросов.
Проверить мне не начем.

Спускайте (select ... from ffmaprep ... group by article) вниз, получите 1 тяжелый запрос вместо условно легких миллионов.

Условие по датам упростить
Код:
                        AND f.saledate between ADD_MONTHS (LAST_DAY (SYSDATE), -2) + 1
                                           and ADD_MONTHS (LAST_DAY (SYSDATE), -1)
Артикулы, входящие в матрицы/контракты тоже вынести бы из цикла.
Если оставить на месте, то можно попробовать
Код:
         NVL(
              (select 1
                 from dual
                where exists ( select 1
                                 from supermag.smassortmatrixloc ml,
                                  ...
				AND d1.docstate = 2)),
	  0) AS inmatrix
17.05.2013 12:02
cb
 
select --+parallel (f)
f.article,
SUM((CASE WHEN F.SALEOP=3 THEN F.SALELOCATIONTO ELSE SALELOCATIONFROM END)) AS mx,
SUM((CASE WHEN F.SALEOP=3 THEN (-1)*F.SALESUM ELSE F.SALESUM END)) AS SALESUM,
SUM((CASE WHEN F.SALEOP=3 THEN (-1)*(F.SALESUM-F.PRIMECOST) ELSE (F.SALESUM-F.PRIMECOST) END)) AS DOXOD,
SUM((CASE WHEN F.SALEOP=3 THEN (-1)*F.SALEQ ELSE F.SALEQ END)) AS SALEQ
from FFMAPREP f
where saledate between to_date('01-04-2013', 'dd-mm-yyyy') and to_date('30-04-2013', 'dd-mm-yyyy')
and f.saleop in (1,3)
group by f.article, F.SALELOCATIONFROM, F.SALELOCATIONTO

Вот навскидку как каркас.
Часовой пояс GMT +3, время: 16:18.

Форум на базе vBulletin®
Copyright © Jelsoft Enterprises Ltd.
В случае заимствования информации гипертекстовая индексируемая ссылка на Форум обязательна.