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)
必须有办法让这个查询的资源消耗更少,但我不知道该怎么做。想法和建议?
答案 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