我的慢速T-SQL查询需要重新考虑

Rob*_*ert 1 sql t-sql sql-server stored-procedures sql-server-2005

大家下午好。我将在整个过程中发布存储过程。随意将其撕成碎片。作者不会介意的。

DECLARE @itemTypeID INT
SELECT @itemTypeID=ItemTypeID FROM dbo.ItemTypes WHERE ItemTypeName = 'Advert'

BEGIN
 SELECT a.Active,
   a.ParentClass,
   a.Classification,
   a.Variant,
   FV."Full Views",
   PV."Print Views",
   EE."Email Enquiries",
   a.ItemRef,
   a.SiteID
 FROM 
 (
 SELECT DISTINCT i.ItemID,
   i.ItemRef,
   i.SiteID,
   i.ParentClass,
   i.Classification,
   i.Summary AS "Variant",       
   i.Active
 FROM Items i
 JOIN Actions a
 ON a.ItemID = i.ItemID
 JOIN ActionTypes at 
 ON a.ActionTypeID = at.ActionTypeID
 WHERE i.ItemTypeID = 1
 AND a.DateAndTime BETWEEN @startDate AND @endDate
 AND at.ActionTypeName IN ('Full view', 'Print view', 'Email enquiry')
 AND ((@siteID = -1) OR (i.SiteID = @siteID))
 AND ((@parentClass = '%') OR (i.ParentClass = @parentClass))
 AND ((@class = '%') OR (i.classification = @class))
 ) a LEFT JOIN
 (
 SELECT i.ItemID, 
   COUNT(*) AS "Full Views"
 FROM CustomerSites cs JOIN Items i
 ON cs.SiteID = i.SiteID
 JOIN Actions a
 ON a.ItemID = i.ItemID
 JOIN ActionTypes at 
 ON a.ActionTypeID = at.ActionTypeID
 JOIN Sites s
 ON cs.SiteID = s.SiteID
 WHERE a.DateAndTime BETWEEN @startDate AND @endDate
 AND i.ItemTypeID = @itemTypeID
 AND at.ActionTypeName = 'Full view'
 AND ((@customerID IS NULL) OR (cs.CustomerID = @customerID))
 AND ((@siteID = -1) OR (cs.SiteID = @siteID))
 AND ((@parentClass = '%') OR (i.ParentClass = @parentClass))
 AND ((@class = '%') OR (i.classification = @class))
 GROUP BY
   i.ItemID
 ) FV 
 ON a.ItemID = FV.ItemID
 LEFT JOIN
 (
 SELECT i.ItemID,
   COUNT(*) AS "Print Views"
 FROM CustomerSites cs JOIN Items i
 ON cs.SiteID = i.SiteID
 JOIN Actions a
 ON a.ItemID = i.ItemID
 JOIN ActionTypes at 
 ON a.ActionTypeID = at.ActionTypeID
 JOIN Sites s
 ON cs.SiteID = s.SiteID
 WHERE a.DateAndTime BETWEEN @startDate AND @endDate
 AND i.ItemTypeID = @itemTypeID
 AND at.ActionTypeName = 'Print view'
 AND ((@customerID IS NULL) OR (cs.CustomerID = @customerID))
 AND ((@siteID = -1) OR (cs.SiteID = @siteID))
 AND ((@parentClass = '%') OR (i.ParentClass = @parentClass))
 AND ((@class = '%') OR (i.classification = @class))
 GROUP BY
   i.ItemID
 ) PV 
 ON a.ItemID = PV.ItemID
 LEFT JOIN
 (
 SELECT i.ItemID,
   COUNT(*) AS "Email Enquiries"
 FROM CustomerSites cs JOIN Items i
 ON cs.SiteID = i.SiteID
 JOIN Actions a
 ON a.ItemID = i.ItemID
 JOIN ActionTypes at 
 ON a.ActionTypeID = at.ActionTypeID
 JOIN Sites s
 ON cs.SiteID = s.SiteID
 WHERE a.DateAndTime BETWEEN @startDate AND @endDate
 AND i.ItemTypeID = @itemTypeID
 AND at.ActionTypeName = 'Email enquiry'
 AND ((@customerID IS NULL) OR (cs.CustomerID = @customerID))
 AND ((@siteID = -1) OR (cs.SiteID = @siteID))
 AND ((@parentClass = '%') OR (i.ParentClass = @parentClass))
 AND ((@class = '%') OR (i.classification = @class))
 GROUP BY
   i.ItemID
 ) EE
 ON a.ItemID = EE.ItemID
 UNION
 SELECT '0','','','','','','','',''
Run Code Online (Sandbox Code Playgroud)

现在,最终所有这些操作将返回一些记录以及针对这些记录执行特定操作的次数。

一小部分看起来像。

项目描述查看打印的电子邮件

Item1 Desc1 12 NULL 1
Item2 Desc2 NULL NULL 3
Item3 Desc3 5 6 2
Run Code Online (Sandbox Code Playgroud)

希望您能看到发生了什么事。

我想要一个列表,该列表针对特定站点的特定客户在特定日期范围内针对特定日期对它们执行了操作,并且该查询应可针对父类和分类进行过滤。好啊

第一次选择将返回符合选择标准的所有不同项目。

其他3个查询全部针对每个项目简单地返回一种动作类型的计数。即使是少量数据,查询也很慢。这永远不会上线,只是行不通。

希望您能看到“作者”方式的错误并纠正他/她。

KM.*_*KM. 5

这是我的格式化样式的原始查询:

SELECT  
    a.Active
        ,a.ParentClass
        ,a.Classification
        ,a.Variant
        ,FV."Full Views"
        ,PV."Print Views"
        ,EE."Email Enquiries"
        ,a.ItemRef
        ,a.SiteID
    FROM (SELECT DISTINCT
              i.ItemID,
                  ,i.ItemRef
                  ,i.SiteID
                  ,i.ParentClass
                  ,i.Classification
                  ,i.Summary AS "Variant"
                  ,i.Active
              FROM Items              i
                  JOIN Actions        a ON a.ItemID = i.ItemID
                  JOIN ActionTypes   at ON a.ActionTypeID = at.ActionTypeID
              WHERE i.ItemTypeID = 1
                  AND a.DateAndTime BETWEEN @startDate AND @endDate
                  AND at.ActionTypeName IN ('Full view', 'Print view', 'Email enquiry')
                  AND ((@siteID = -1) OR (i.SiteID = @siteID))
                  AND ((@parentClass = '%') OR (i.ParentClass = @parentClass))
                  AND ((@class = '%') OR (i.classification = @class))
        ) a
        LEFT JOIN (SELECT  
                       i.ItemID
                           ,COUNT(*) AS "Full Views"
                       FROM CustomerSites          cs
                           JOIN Items               i ON cs.SiteID = i.SiteID
                           JOIN Actions             a ON a.ItemID = i.ItemID
                           JOIN ActionTypes        at ON a.ActionTypeID = at.ActionTypeID
                           JOIN Sites               s ON cs.SiteID = s.SiteID
                      WHERE a.DateAndTime BETWEEN @startDate AND @endDate
                          AND i.ItemTypeID = @itemTypeID
                          AND at.ActionTypeName = 'Full view'
                          AND ((@customerID IS NULL) OR (cs.CustomerID = @customerID))
                          AND ((@siteID = -1) OR (cs.SiteID = @siteID))
                          AND ((@parentClass = '%') OR (i.ParentClass = @parentClass))
                          AND ((@class = '%') OR (i.classification = @class))
                      GROUP BY i.ItemID
                  ) FV ON a.ItemID = FV.ItemID
        LEFT JOIN (SELECT
                       i.ItemID
                           ,COUNT(*) AS "Print Views"
                       FROM CustomerSites      cs 
                           JOIN Items           i ON cs.SiteID = i.SiteID
                           JOIN Actions         a ON a.ItemID = i.ItemID
                           JOIN ActionTypes    at ON a.ActionTypeID = at.ActionTypeID
                           JOIN Sites           s ON cs.SiteID = s.SiteID
                       WHERE a.DateAndTime BETWEEN @startDate AND @endDate
                           AND i.ItemTypeID = @itemTypeID
                           AND at.ActionTypeName = 'Print view'
                           AND ((@customerID IS NULL) OR (cs.CustomerID = @customerID))
                           AND ((@siteID = -1) OR (cs.SiteID = @siteID))
                           AND ((@parentClass = '%') OR (i.ParentClass = @parentClass))
                           AND ((@class = '%') OR (i.classification = @class))
                       GROUP BY i.ItemID
                  ) PV ON a.ItemID = PV.ItemID
        LEFT JOIN (SELECT
                       i.ItemID
                           ,COUNT(*) AS "Email Enquiries"
                       FROM CustomerSites   cs
                           JOIN Items        i ON cs.SiteID = i.SiteID
                           JOIN Actions      a ON a.ItemID = i.ItemID
                           JOIN ActionTypes at ON a.ActionTypeID = at.ActionTypeID
                           JOIN Sites        s ON cs.SiteID = s.SiteID
                       WHERE a.DateAndTime BETWEEN @startDate AND @endDate
                           AND i.ItemTypeID = @itemTypeID
                           AND at.ActionTypeName = 'Email enquiry'
                           AND ((@customerID IS NULL) OR (cs.CustomerID = @customerID))
                           AND ((@siteID = -1) OR (cs.SiteID = @siteID))
                           AND ((@parentClass = '%') OR (i.ParentClass = @parentClass))
                           AND ((@class = '%') OR (i.classification = @class))
                       GROUP BY i.ItemID
                  ) EE ON a.ItemID = EE.ItemID
UNION
SELECT '0','','','','','','','',''
Run Code Online (Sandbox Code Playgroud)

这应该会有所帮助:

;WITH CustomerSitesCounts AS
(
SELECT
    at.ActionTypeName
        ,i.ItemID
        ,COUNT(*) AS "Print Views"
    FROM CustomerSites      cs 
        JOIN Items           i ON cs.SiteID = i.SiteID
        JOIN Actions         a ON a.ItemID = i.ItemID
        JOIN ActionTypes    at ON a.ActionTypeID = at.ActionTypeID
        JOIN Sites           s ON cs.SiteID = s.SiteID
    WHERE a.DateAndTime BETWEEN @startDate AND @endDate
        AND i.ItemTypeID = @itemTypeID
        AND at.ActionTypeName IN ( 'Print view','Full view','Email enquiry')
        AND ((@customerID IS NULL) OR (cs.CustomerID = @customerID))
        AND ((@siteID = -1) OR (cs.SiteID = @siteID))
        AND ((@parentClass = '%') OR (i.ParentClass = @parentClass))
        AND ((@class = '%') OR (i.classification = @class))
    GROUP BY at.ActionTypeName,i.ItemID
)
SELECT  
    a.Active
        ,a.ParentClass
        ,a.Classification
        ,a.Variant
        ,FV."Full Views"
        ,PV."Print Views"
        ,EE."Email Enquiries"
        ,a.ItemRef
        ,a.SiteID
    FROM (SELECT DISTINCT
              i.ItemID,
                  ,i.ItemRef
                  ,i.SiteID
                  ,i.ParentClass
                  ,i.Classification
                  ,i.Summary AS "Variant"
                  ,i.Active
              FROM Items              i
                  JOIN Actions        a ON a.ItemID = i.ItemID
                  JOIN ActionTypes   at ON a.ActionTypeID = at.ActionTypeID
              WHERE i.ItemTypeID = 1
                  AND a.DateAndTime BETWEEN @startDate AND @endDate
                  AND at.ActionTypeName IN ('Full view', 'Print view', 'Email enquiry')
                  AND ((@siteID = -1) OR (i.SiteID = @siteID))
                  AND ((@parentClass = '%') OR (i.ParentClass = @parentClass))
                  AND ((@class = '%') OR (i.classification = @class))
        ) a
        LEFT JOIN CustomerSitesCounts FV ON a.ItemID = FV.ItemID AND FV.ActionTypeName='Full view'
        LEFT JOIN CustomerSitesCounts PV ON a.ItemID = PV.ItemID AND PV.ActionTypeName='Print view'
        LEFT JOIN CustomerSitesCounts EE ON a.ItemID = EE.ItemID AND EE.ActionTypeName='Email enquiry'
UNION
SELECT '0','','','','','','','',''
Run Code Online (Sandbox Code Playgroud)