mch_dk
mch_dk

Reputation: 369

SQL optimization/tweaking

I have this SQL Server query

SELECT count(distinct [IP]) as GlobalUniqueIPcount, 
    --RangeUniqueIPcount
    (SELECT count(distinct [IP]) FROM [tblSequence] WHERE SiteID = @siteID AND ([Timestamp] > DATEADD(dd, -@days, (LEFT(GETDATE(),12))))) as RangeUniqueIPcount,
    --RangeUrlUniqueIPcount
    (SELECT count(distinct [IP]) FROM [tblSequence] WHERE SiteID = @siteID AND ([Timestamp] > DATEADD(dd, -@days, (LEFT(GETDATE(),12)))) AND Url = @Url) as RangeUrlUniqueIPcount,
    --RangeUniquePageviews
    (SELECT count (distinct url + SessionGuid) FROM [tblSequence] WHERE SiteID = @siteID AND ([Timestamp] > DATEADD(dd, -@days, (LEFT(GETDATE(),12))))) as RangeUniquePageViews,
    --RangeUrlUniquePageviews
    (SELECT count (distinct url + SessionGuid) FROM [tblSequence] WHERE SiteID = @siteID AND ([Timestamp] > DATEADD(dd, -@days, (LEFT(GETDATE(),12)))) AND Url = @Url) as RangeUrlUniquePageViews,  
    --GlobalUniquePageViews
    (SELECT count (distinct url + SessionGuid) FROM [tblSequence] WHERE SiteID = @siteID) as GlobalUniquePageViews
FROM [tblSequence] WHERE SiteID = @siteID

I have more than 1,000,000 rows and it performs like crap. What to do - please help.

Thanks a lot

Upvotes: 1

Views: 204

Answers (2)

gbn
gbn

Reputation: 432210

No wonder it runs slow: you have 5 correlated subqueries, 2 of which are unnecessary and 3 can be re-written. Try this.

Also, you need an index on one of these, can't say exactly which

  1. (SiteID, Timestamp, Url) with INCLUDE on (IP, SessionGuid)
    • (SiteID, Timestamp) with INCLUDE on (IP, SessionGuid, Url)
    • (SiteID) with INCLUDE on (IP, Url, SessionGuid, Timestamp)

It depends on whether the 1st tow would be used RangeMatch and URLmatch. My guess is number 2 or 3 will be needed. It matters for index size.

Count will ignore NULLs when * is not used.

SELECT
    count(distinct [IP]) as GlobalUniqueIPcount, 

    --RangeUniqueIPcount
    count (distinct CASE
             WHEN RangeMatch = 1 
             THEN IP ELSE NULL
           END ) AS RangeUniqueIPcount,

    --RangeURLUniqueIPcount
    count (distinct CASE
             WHEN RangeMatch = 1  AND UrlMatch = 1
             THEN IP ELSE NULL
           END ) AS RangeURLUniqueIPcount,

    --RangeUniquePageviews
    count (distinct CASE
             WHEN RangeMatch = 1 
             THEN url + SessionGuid ELSE NULL
           END ) RangeUniquePageViews,

    --RangeUrlUniquePageviews
    count (distinct CASE
             WHEN RangeMatch = 1 AND UrlMatch = 1
             THEN url + SessionGuid ELSE NULL
           END ) RangeUrlUniquePageViews,

    --GlobalUniquePageViews
    count (distinct url + SessionGuid) as GlobalUniquePageViews
FROM
  (SELECT
    *, 
    CASE WHEN  Url = @Url THEN 1 ELSE 0 END AS UrlMatch,
    CASE WHEN [Timestamp] > DATEADD(dd, -@days, (LEFT(GETDATE(),12))) THEN 1 ELSE 0 END AS RangeMatch
  FROM
     [tblSequence]
  WHERE SiteID = @siteID
  ) foo

Upvotes: 3

JohnB
JohnB

Reputation: 18972

Do IP SiteID, Timestamp, url, and SessionGuid already have indexes?

Upvotes: 0

Related Questions