2013-05-07 83 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