繁体   English   中英

有没有更有效的方式编写此SQL查询?

[英]Is there a more efficient way to write this SQL query?

我有一个表,其中有几百万条记录,其中存储着SessionGUID(访客)的产品视图,该表的结构为:

ID(PK)SessionGUID(唯一标识符)ProductID(整数)DateTime(日期时间)

该查询的目的是返回由查看特定产品ID的同一人查看过的产品ID的列表(即,查看X的客户也查看了Y)

我正在使用的查询如下:

SELECT
A.ProductID
FROM
VISITOR_SESSIONS_PRODUCTVIEWS A
WHERE
A.SessionGUID IN (SELECT DISTINCT SessionGUID FROM VISITOR_SESSIONS_PRODUCTVIEWS WHERE ProductID = @ProductID)
GROUP BY
A.ProductID
ORDER BY
COUNT(A.ProductID) DESC

有没有更有效的方式使用GROUP BY / HAVING / PARTITON编写此代码,或者是否有其他更优化的方法来按我需要的方式获取数据?

我在开发服务器上运行SQL 2008,但上线时将通过SQL Azure运行。

通常, EXISTSIN更有效:

SELECT A.ProductID
FROM VISITOR_SESSIONS_PRODUCTVIEWS A
WHERE EXISTS (SELECT 1
              FROM VISITOR_SESSIONS_PRODUCTVIEWS B
              WHERE B.ProductID = @ProductID AND
                    A.SessionGUID = B.SessionGUID
             )
GROUP BY A.ProductID
ORDER BY COUNT(A.ProductID) DESC;

为了获得最佳性能,您需要在VISITOR_SESSIONS_PRODUCTVIEWS(SessionGUID, ProductId)以及VISITOR_SESSIONS_PRODUCTVIEWS(ProductId)上建立索引。

编辑:

您可以尝试使用窗口函数编写此代码,但是我不确定性能会更好:

select productid
from (select pv.*,
             sum(case when productid = @productid then 1 else 0 end) over (partition by SessionGUID) as cnt
      from visitor_sessions_productviews 
     ) pv
where cnt > 0
group by productid
order by count(*) desc;

我不确定性能是否会比EXISTS方法更好。

您可以通过以下几种方法写出更好的效果:

  • 临时会话表,然后通过这些会话加入VISITOR_SESSIONS_PRODUCTVIEWS
  • 加入带有产品的VISITOR_SESSIONS_PRODUCTVIEWS会话,然后通过这些会话重新加入VISITOR_SESSIONS_PRODUCTVIEWS
  • 使用EXISTS而不是DISTINCT来查询该用户会话中存在问题的产品

这是临时表解决方案:

SELECT DISTINCT SessionGUID 
INTO #sessionsWithProduct
FROM VISITOR_SESSIONS_PRODUCTVIEWS
WHERE ProductID = @ProductID;

SELECT
    A.ProductID
FROM VISITOR_SESSIONS_PRODUCTVIEWS A
    INNER JOIN #sessionsWithProduct S ON s.SessionGUID = A.SessionGUID
GROUP BY A.ProductID
ORDER BY COUNT(A.ProductID) DESC;

DROP TABLE #sessionsWithProduct;

也是非常重要的是要确保这个表至少索引的产品ID和SessionGUID(各一个)。

SELECT A.ProductID
  FROM VISITOR_SESSIONS_PRODUCTVIEWS A
  JOIN VISITOR_SESSIONS_PRODUCTVIEWS S
    ON A.SessionGUID = S.SessionGUID 
   AND S.ProductID = @ProductID 
 GROUP B A.ProductID
 ORDER BY COUNT(DISTINCT(A.ProductID)) DESC

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM