2013-05-07 85 views
1

参照SQL Query how to summarize students record by date?我能够得到我想要的报告。如何提高此查询的性能?

我被告知在现实世界中学生表将有30百万条记录。我有索引(StudentID,Date)。任何提高性能的建议或是否有更好的方法来构建报告?

现在我有以下查询

;with cte as 
(
    select id, 
    studentid, 
    date, 
    '#'+subject+';'+grade+';'+convert(varchar(10), date, 101) report 
    from student 
) 
-- insert into studentreport 
select distinct 
    studentid, 
    STUFF(
     (SELECT cast(t2.report as varchar(50)) 
      FROM cte t2 
      where c.StudentId = t2.StudentId 
      order by t2.date desc 
      FOR XML PATH ('')) 
      , 1, 0, '') AS report 
from cte c; 
+0

执行计划在哪里? – 2013-05-07 18:24:12

+0

;具有热膨胀系数为 ( 选择ID, studentid, 日期, '#' +主语+ ';' +等级+ ';' +转换(VARCHAR(10)日,101)从学生 报告 ) - 插入studentreport 选择不同 studentid, STUFF( (其中c.StudentId = t2.StudentId 为了通过t2.date降序 FOR SELECT CAST(t2.report为varchar(50)) FROM CTE T2 XML PATH('')) ,1,0,'')AS报告 from cte c; – Think 2013-05-07 18:24:47

+3

日期范围意味着正在处理的记录更少。这会提高性能。这可能会让你的报告更加相关。 – 2013-05-07 18:34:46

回答

1

没有看到执行计划,它不是真的可以编写优化的SQL语句,所以我会提出建议来代替。

不要使用cte,因为他们经常无法处理大内存查询需要(至少,根据我的经验)。相反,将cte数据放在一个真正的表中,可以使用物化/索引视图或工作表(可能是一个大的临时表)。然后执行第二次选择(在cte之后)将数据组合到有序列表中。

对您问题的评论数表明您有大问题(或问题)。你正在将高瘦的数据(认为整数,datetime2类型)转换为字符串中的有序列表。尝试思考,而不是以可用的最小数据格式进行存储,并在以后(或从不)以字符串形式操作。或者,认真考虑创建XML数据字段以替换“报告”字段。

如果你能使它工作,这是我会做的(包括没有索引的测试用例)。您的里程可能会有所不同,但请试试看:

create table #student (id int not null, studentid int not null, date datetime not null, subject varchar(40), grade varchar(40)) 

insert into #student (id,studentid,date,subject,grade) 
select 1, 1, getdate(), 'history', 'A-' union all 
select 2, 1, dateadd(d,1,getdate()), 'computer science', 'b' union all 
select 3, 1, dateadd(d,2,getdate()), 'art', 'q' union all 
-- 
select 1, 2, getdate() , 'something', 'F' union all 
select 2, 2, dateadd(d,1,getdate()), 'genetics', 'e' union all 
select 3, 2, dateadd(d,2,getdate()), 'art', 'D+' union all 
-- 
select 1, 3, getdate() , 'memory loss', 'A-' union all 
select 2, 3, dateadd(d,1,getdate()), 'creative writing', 'A-' union all 
select 3, 3, dateadd(d,2,getdate()), 'history of asia 101', 'A-' 

go 

select  studentid as studentid 
      ,(select s2.date as '@date', s2.subject as '@subject', s2.grade as '@grade' 
      from #student s2 where s1.studentid = s2.studentid for xml path('report'), type) as 'reports' 
from  (select distinct studentid from #student) s1; 

我不知道如何使输出清晰可见,但结果集是2个字段。字段1是一个整数,字段2是XML,每个报表有一个节点。这还不如发送结果集那么理想,但每个studentid至少有一个结果。

+0

这是我的想法太 - 一个CTE可能是减缓下来创建不需要额外的步骤。 – Jasmine 2013-05-09 20:39:38

+0

非常感谢您的建议。我确实删除并直接编写了查询。尽管如此,它的时间还是比CTE更好。 – Think 2013-05-14 21:45:22