[英]How to improve performance of this query?
參照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;
如果不查看執行計划,實際上不可能編寫優化的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,每個報表一個節點。 這仍然不像發送結果集那樣理想,但是每個學生ID至少有一個結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.