SQL Server:如何使此查询更有效/更快?

时间:2018-05-01 14:25:46

标签: sql sql-server database

SQL Wizards& amp;掌握那里。我必须把这个野兽的执行时间缩短。执行时间超过5分钟,偶尔会超时。我需要帮助了解如何提高效率。我回来了大约10万行。

场景是:我正在尝试识别应该被标记为“约会季节”#34;的“有效订单”。这些订单将包含与有效“类别代码”相关联的项目(dbo.DTITEMS ON od.CATEGORY = dbo.DTITEMS.CATEGORY)。

然后我使用此查询的结果基本上使用当前"约会季节的值更新订单字段“DTGSEASON”。"

我引用了一个名为DATING的表(与CRM.Dbo.Dating分开),该表存储了诸如Promotion Start& amp;结束日期,当前约会季节等。

这是我正在运行的查询'有效订单',名为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 :(得分:0)

这两个查询都存在逻辑问题。你有一个左连接到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