我正在对我们为客户提供的内部web分析系统进行一些升级(在没有首选供应商或Google analytics的情况下),我正在进行以下查询:
select
path as EntryPage,
count(Path) as [Count]
from
(
/* Sub-query 1 */
select
pv2.path
from
pageviews pv2
inner join
(
/* Sub-query 2 */
select
pv1.sessionid,
min(pv1.created) as created
from
pageviews pv1
inner join Sessions s1 on pv1.SessionID = s1.SessionID
inner join Visitors v1 on s1.VisitorID = v1.VisitorID
where
pv1.Domain = isnull(@Domain, pv1.Domain) and
v1.Campaign = @Campaign
group by
pv1.sessionid
) t1 on pv2.sessionid = t1.sessionid and pv2.created = t1.created
) t2
group by
Path;我已经用PageViews表中的200万行测试了这个查询,运行时间约为20秒。我注意到在执行计划中进行了两次聚集索引扫描,这两次都是针对PageViews表的。该表中创建的列上有一个聚集索引。
问题是,在这两种情况下,它似乎迭代了所有的200万行,我认为这是性能瓶颈。我能做些什么来防止这种情况吗?还是说我的优化工作已经达到了极限呢?
作为参考,查询的目的是查找每个会话的第一个页面视图。
编辑:在经历了很多挫折之后,尽管在这里收到了帮助,但我无法使这个查询工作。因此,我决定简单地将对条目页(现在是退出页)的引用存储在sessions表中,这样我就可以执行以下操作:
select
pv.Path,
count(*)
from
PageViews pv
inner join Sessions s on pv.SessionID = s.SessionID
and pv.PageViewID = s.ExitPage
inner join Visitors v on s.VisitorID = v.VisitorID
where
(
@Domain is null or
pv.Domain = @Domain
) and
v.Campaign = @Campaign
group by pv.Path;此查询在3秒或更短的时间内运行。现在,我要么必须在记录页面视图时实时更新输入/退出页面(最佳解决方案),要么在某个时间间隔运行批处理更新。不管怎样,它解决了问题,但不像我想的那样。
编辑编辑:添加一个缺少的索引(昨晚清理之后),将查询减少到仅仅毫秒)。喔呼!
发布于 2008-12-04 04:26:11
您的内部查询(pv1)将需要(域)上的非聚集索引。
由于创建了聚集索引,第二个查询(pv2)已经可以找到它需要的行,但是pv1可能会返回太多行,因此Server决定表扫描比它需要使用的所有锁都要快。由于pv1组在SessionID上(因此必须按SessionID排序),创建了SessionID上的非聚集索引,并且包含路径,应该允许合并连接发生。如果没有,可以强制使用"SELECT .从页面查看pv2内部合并联接.“进行合并连接。
上面列出的两个指数是:
在PageViews (域)上创建非NONCLUSTERED索引域
在PageViews上创建非NONCLUSTERED索引ncixsessionidcreated (SessionID,已创建)包含(路径)
https://stackoverflow.com/questions/339560
复制相似问题