SQL Server: как сделать этот запрос более эффективным / быстрым? - PullRequest
0 голосов
/ 01 мая 2018

Вопрос для мастеров и мастеров SQL. Я должен сократить время казни этого зверя. Выполнение занимает более 5 минут и время от времени. Мне нужна помощь, чтобы понять, как сделать это более эффективным. Я возвращаю около 100 000 строк.

Сценарий таков: я пытаюсь определить «действительные заказы», ​​которые следует пометить для чего-то, называемого «сезон знакомств». У этих заказов будут элементы, связанные с действительными «кодами категорий» (dbo.DTITEMS ON od.CATEGORY = dbo.DTITEMS.CATEGORY).

Затем я использую результаты этого запроса, чтобы в основном обновить поле заказа «DTGSEASON» значением текущего «сезона датирования».

Я ссылаюсь на таблицу под названием DATING (отдельно от CRM.Dbo.Dating), в которой хранятся такие параметры, как даты начала и окончания рекламной акции, текущий сезон датировок и т. Д.

Вот запрос, который я выполняю, чтобы найти «Действительные заказы», ​​который называется vDatingValidOrdersReg:

SELECT     
      h.CUSTOMER
    , h.ORDNUMBER
    , h.INVNETWTX
    , dtgseason.VALUE AS dtgseason
    , c.comp_dqdatingmin
    , dbo.DTITEMS.ALTMINIMUM
    , d.dat_datingapprovedon
    , d.dat_ordsincepromostart
    , h.EXPDATE
    , dbo.DATING.PROMOSTART
    , d.dat_season
    , d.dat_year
    , od.ITEM
    , od.CATEGORY
    , d.dat_DatingID
    , c.Comp_Name
    , d.dat_state
    , h.ORDUNIQ
    , c.comp_dqdatingmax
FROM CRM.dbo.Dating AS d 
INNER JOIN CRM.dbo.Company AS c 
    ON d.dat_CompanyId = c.Comp_CompanyId 
LEFT OUTER JOIN dbo.OEORDH AS h 
    ON c.Comp_IdCust = h.CUSTOMER 
LEFT OUTER JOIN dbo.OEORDHO AS dtgseason 
    ON h.ORDUNIQ = dtgseason.ORDUNIQ AND dtgseason.OPTFIELD = 'dtgseason'
INNER JOIN dbo.OEORDD AS od 
    ON h.ORDUNIQ = od.ORDUNIQ 
INNER JOIN dbo.DTITEMS 
    ON od.CATEGORY = dbo.DTITEMS.CATEGORY 
INNER JOIN dbo.DATING 
    ON d.dat_season = dbo.DATING.SEASON 
    AND d.dat_year = dbo.DATING.YEAR 
    AND dbo.DTITEMS.SEASON = dbo.DATING.SEASON 
    AND dbo.DTITEMS.YEAR = dbo.DATING.YEAR
WHERE (h.ORDDATE BETWEEN dbo.DATING.PROMOSTART AND dbo.DATING.PROMOEND) 
    AND (h.EXPDATE BETWEEN dbo.DATING.EXPSHIPST AND dbo.DATING.EXPSHIPEND) 
    AND (d.dat_state = 'Approve') 
    AND (d.dat_Deleted IS NULL) 
    AND (dbo.DATING.SEASCLOSED = 0) 
    AND (dbo.DTITEMS.ALTMINIMUM = 0) 
    AND (h.ORDNUMBER NOT IN (
                             SELECT     ORDNUMBER
                             FROM       dbo.vDatingValidOrdersAlt)) 
    AND (dbo.DATING.ORDERON = 1)

Вот запрос, на который он ссылается, в основном это одно и то же, но он ищет заказы с различными категориями элементов: vDatingValidOrdersAlt. Это моя проблема?

SELECT     
    h.CUSTOMER
    , h.ORDNUMBER
    , h.INVNETWTX
    , dtgseason.VALUE AS dtgseason
    , c.comp_dqdatingmin
    , dbo.DTITEMS.ALTMINIMUM
    , d.dat_datingapprovedon
    , d.dat_ordsincepromostart
    , h.EXPDATE
    , dbo.DATING.PROMOSTART
    , d.dat_season
    , d.dat_year
    , od.ITEM
    , od.CATEGORY
    , d.dat_DatingID
    , c.Comp_Name
    , d.dat_state
    , h.ORDUNIQ, c.comp_dqdatingmax
FROM CRM.dbo.Dating AS d 
INNER JOIN CRM.dbo.Company AS c 
    ON d.dat_CompanyId = c.Comp_CompanyId 
LEFT OUTER JOIN dbo.OEORDH AS h 
    ON c.Comp_IdCust = h.CUSTOMER 
LEFT OUTER JOIN dbo.OEORDHO AS dtgseason 
    ON h.ORDUNIQ = dtgseason.ORDUNIQ AND dtgseason.OPTFIELD = 'dtgseason' 
INNER JOIN dbo.OEORDD AS od 
    ON h.ORDUNIQ = od.ORDUNIQ 
INNER JOIN dbo.DTITEMS 
    ON od.CATEGORY = dbo.DTITEMS.CATEGORY 
INNER JOIN dbo.DATING 
    ON d.dat_season = dbo.DATING.SEASON 
    AND d.dat_year = dbo.DATING.YEAR 
    AND dbo.DTITEMS.SEASON = dbo.DATING.SEASON 
    AND dbo.DTITEMS.YEAR = dbo.DATING.YEAR
WHERE (h.ORDDATE BETWEEN dbo.DATING.PROMOSTART AND dbo.DATING.PROMOEND) 
    AND (h.EXPDATE BETWEEN dbo.DATING.EXPSHIPST AND dbo.DATING.EXPSHIPEND)
    AND (d.dat_state = 'Approve') 
    AND (d.dat_Deleted IS NULL) 
    AND (dbo.DATING.SEASCLOSED = 0) 
    AND (dbo.DTITEMS.ALTMINIMUM > 0) 
    AND (dbo.DATING.ORDERON = 1)

Должен быть способ сделать этот запрос менее ресурсоемким, но я не уверен, как это сделать. Мысли и предложения?

1 Ответ

0 голосов
/ 01 мая 2018

У вас есть логическая проблема в обоих этих запросах. У вас есть левое соединение с dbo.OEORDH, но затем есть предложение where для этой таблицы. Это логически меняет ваше левое соединение на внутреннее соединение. Что касается производительности, я не вижу ничего вопиющего, что вы можете изменить в вашем sql. Однако я был бы удивлен, если бы у вас были индексы для этих запросов. Нам нужно увидеть определение таблицы и индексы. Кроме того, размещение планов выполнения было бы крайне важно для выяснения этого.

Вот как эти два запроса могут выглядеть при некотором форматировании.

SELECT h.CUSTOMER
    , h.ORDNUMBER
    , h.INVNETWTX
    , dtgseason.VALUE AS dtgseason
    , c.comp_dqdatingmin
    , di.ALTMINIMUM
    , d.dat_datingapprovedon
    , d.dat_ordsincepromostart
    , h.EXPDATE
    , dd.PROMOSTART
    , d.dat_season
    , d.dat_year
    , od.ITEM
    , od.CATEGORY
    , d.dat_DatingID
    , c.Comp_Name
    , d.dat_state
    , h.ORDUNIQ
    , c.comp_dqdatingmax
FROM CRM.dbo.Dating AS d 
INNER JOIN CRM.dbo.Company AS c ON d.dat_CompanyId = c.Comp_CompanyId 
LEFT OUTER JOIN dbo.OEORDH AS h ON c.Comp_IdCust = h.CUSTOMER 
LEFT OUTER JOIN dbo.OEORDHO AS dtgseason ON h.ORDUNIQ = dtgseason.ORDUNIQ 
                                        AND dtgseason.OPTFIELD = 'dtgseason' 
INNER JOIN dbo.OEORDD AS od ON h.ORDUNIQ = od.ORDUNIQ 
INNER JOIN dbo.DTITEMS di ON od.CATEGORY = di.CATEGORY 
INNER JOIN dbo.DATING dd ON d.dat_season = dd.SEASON 
                        AND d.dat_year = dd.YEAR 
                        AND di.SEASON = dd.SEASON 
                        AND di.YEAR = dd.YEAR
WHERE h.ORDDATE BETWEEN dd.PROMOSTART AND dd.PROMOEND
    AND h.EXPDATE BETWEEN dd.EXPSHIPST AND dd.EXPSHIPEND
    AND d.dat_state = 'Approve'
    AND d.dat_Deleted IS NULL
    AND dd.SEASCLOSED = 0
    AND di.ALTMINIMUM = 0
    AND h.ORDNUMBER NOT IN (SELECT ORDNUMBER FROM dbo.vDatingValidOrdersAlt)
    AND dd.ORDERON = 1

И второй.

SELECT h.CUSTOMER
    , h.ORDNUMBER
    , h.INVNETWTX
    , dtgseason.VALUE AS dtgseason
    , c.comp_dqdatingmin
    , di.ALTMINIMUM
    , d.dat_datingapprovedon
    , d.dat_ordsincepromostart
    , h.EXPDATE
    , dd.PROMOSTART
    , d.dat_season
    , d.dat_year
    , od.ITEM
    , od.CATEGORY
    , d.dat_DatingID
    , c.Comp_Name
    , d.dat_state
    , h.ORDUNIQ
    , c.comp_dqdatingmax
FROM CRM.dbo.Dating AS d 
INNER JOIN CRM.dbo.Company AS c ON d.dat_CompanyId = c.Comp_CompanyId 
LEFT OUTER JOIN dbo.OEORDH AS h ON c.Comp_IdCust = h.CUSTOMER 
LEFT OUTER JOIN dbo.OEORDHO AS dtgseason ON h.ORDUNIQ = dtgseason.ORDUNIQ 
                                        AND dtgseason.OPTFIELD = 'dtgseason' 
INNER JOIN dbo.OEORDD AS od ON h.ORDUNIQ = od.ORDUNIQ 
INNER JOIN dbo.DTITEMS as di ON od.CATEGORY = di.CATEGORY 
INNER JOIN dbo.DATING as dd ON d.dat_season = dd.SEASON 
                            AND d.dat_year = dd.YEAR 
                            AND di.SEASON = dd.SEASON 
                            AND di.YEAR = dd.YEAR
WHERE h.ORDDATE BETWEEN dd.PROMOSTART AND dd.PROMOEND
    AND h.EXPDATE BETWEEN dd.EXPSHIPST AND dd.EXPSHIPEND
    AND d.dat_state = 'Approve'
    AND d.dat_Deleted IS NULL
    AND dd.SEASCLOSED = 0
    AND di.ALTMINIMUM > 0
    AND dd.ORDERON = 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...