1

参考SQL Query 如何按日期汇总学生记录?我能够得到我想要的报告。

有人告诉我,在现实世界中,学生表将有 3000 万条记录。我确实有(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;
4

1 回答 1

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,每个报告一个节点。这仍然不如仅发送结果集那么理想,但每个学生身份至少有一个结果。

于 2013-05-08T19:08:35.717 回答