問題背景:
給學校的網站添加一個問卷調查系統,新加功能主要包含三張表
Survey 問卷表(用來存儲問卷名)
Survey_Question 問卷問題表(用來存儲問卷問題)
Survey_Answer 問卷答案表(用來存儲問卷的答案)
系統是用ASP來寫的,我應該算是二次開發吧(本人工作經驗尚淺如果名詞表達錯誤請見諒,到現在還是很佩服做這個系統的人,竟然能用ASP寫出一個這么復雜的系統,但維護性。。。真的糾結)
由於本人沒學過ASP。所以一開始還是比較糾結的
最終耗時二個星期的時間完成了以下功能:
1.問卷的添加、修改、刪除
2.問卷問題的添加、修改、刪除
3.開啟問卷調查、關閉問卷調查(每次只允許開啟一張問卷)
4.限制個別專業的學生填寫問卷
5.問卷的統計(包含按專業統計問卷、按系統計問卷、按問題統計問卷、查看不滿意問卷的不滿意原因)PS:問題就出在按專業統計問卷,當然其他統計也應該有類似的問題只是結果較少所以沒有出現這么嚴重的問題。
(不知道小弟的工作效率怎么樣。。。。)
正題(問題出現):
Survey_Answer表的表結構是
ID Student_No SQ_Id(問題ID) A_Content( 問題答案) A_Reason(不滿意問題的理由)
當時統計各專業問卷數據的時 是想着 東西出來就好了所以寫SQL的時候也沒有太在意。能拼出來就很高興了
當時的SQL 是這么寫的(簡寫)(具體的SQL還是比較復雜的。也可能是我寫復雜了,我在文章結尾會附上完整SQL語句)
Select 系,專業,滿意,不滿意,一般,基本滿意,滿意度 ,
from (
left jion (從Survey_Answer里查詢出各專業滿意的數量
left join (從Survey_Answer里查詢出各專業不滿意的數量)
。。。。。。。。。。。。))
就這樣一直將各專業的滿意數量、不滿意數量等一個個查出來然后left join 或right join 進去
當時的想法如下圖
將查詢的結果一個個拼進去。
操作引發的結果:
當有2000個學生填寫后 survey_answer表的數據達到了2W的量(非常小的數據,一個學生填寫11個問題)
當進行查詢的時候發現查詢專業數據統計時竟然需要40秒到1分鍾的時間,
糾結啊
但是放到SQL2008里面則完全不會出現這樣的問題
一樣的查詢語句,一樣的數據 查詢秒查。(SQL2008真心做了不少優化)
解決辦法:
一開始考慮學習原系統的辦法(建立專門建一張表用來存統計數據,然后加一個更新按鈕,點擊更新按鈕就更新數據,否則直接查詢該表的數據)
可是這種方法。。。顯然是很。。。個人認為。。。低級的方案。。
自然不能考慮了。
果斷修改SQL語句,一步步剝離子查詢。然后分析,最終將查詢縮短到了3-5秒
具體操作是這樣的
Select 系,專業,滿意,不滿意,一般,基本滿意,滿意度 ,
from
(從Survey_Answer里查詢出各專業滿意的數量) as t1,
(從Survey_Answer里查詢出各專業不滿意的數量)as t2,
......
通過這樣的拼接來查詢
因為有些數據為0,但你又必須查詢出來,所以我才想到了用join 來做的
問題分析:
個人分析了下應該是這樣的原因
因為學校有37個系
所以在使用join 語句的時候。。。4種結果(滿意,不滿意,基本滿意、一般)應該會做
37*37*37*37 大約200W次吧。。效率自然低下了
而統計系的時候應該是8*8*8*8 的關系所以還不是特別明顯,只是感覺有點慢
(本人的分析可能是有誤,如果知道正確原因的大牛請指點,小弟萬分感謝)
而用了新的SQL語句后。。
效率只是 “+”的關系了,,自然就快了
總結:
小小的總結一下。。。以后寫SQL要注意呀。。。。
------------華麗的分割線-------------
老SQL完整語句:

1 Select isnull((T5.Satisfaction_Count+T5.BSatisfaction_Count)*1.0/nullif(T5.General_Count+T5. BSatisfaction_Count+T5.UnSatisfaction_Count+T5.Satisfaction_Count,0),0) as lastinfo, 2 T6.Faculty_Name as Faculty_Name, T5.Subject_Name as Subject_Name, T5. UnSatisfaction_Count as UnSatisfaction_Count , T5.Satisfaction_Count as Satisfaction_Count, T5.BSatisfaction_Count as BSatisfaction_Count, T5.General_Count as General_Count, T5.Survey_Count as Survey_Count 3 4 from ( 5 select * from Faculty where Faculty.Faculty_Flag=1)as T6 6 -------------------------t5 7 left join 8 ( 9 Select [Subject].Subject_Faculty as Faculty_Id, isnull([Subject].Subject_Name,T4.Subject_Name )as Subject_Name, isnull(T4. UnSatisfaction_Count,0)as UnSatisfaction_Count , 10 isnull(T4.Satisfaction_Count,0)as Satisfaction_Count, isnull(T4.BSatisfaction_Count,0)as BSatisfaction_Count, isnull(T4.General_Count,0)as General_Count, isnull(T4.Survey_Count,0)as Survey_Count 11 from [Subject] 12 -------------------------t4 13 left join 14 ( 15 16 Select isnull(Survey.Subject_Name,T3.Subject_Name )as Subject_Name, (T3. UnSatisfaction_Count) , (T3.Satisfaction_Count) , (T3.BSatisfaction_Count) , (T3.General_Count), Survey.Survey_Count 17 from ( 18 select [Subject].Subject_Name as Subject_Name, count(DISTINCT Survey_Answer.Student_No) as Survey_Count from Student,VClass,[Subject],Survey_Answer,Survey,Survey_Question 19 where VClass.VClass_Subject=[Subject].Subject_Id and VClass.VClass_Id=Student.Student_VClass and Survey.ID=Survey_Question.Survey_ID and Survey_Question.ID=Survey_Answer.SQ_Id 20 and Survey_Answer.Student_No=Student.Student_No and VClass.VClass_Years='2013' and Survey.ID=1 Group by [Subject].Subject_Name 21 ) as Survey 22 -------------------------t3 23 Right join 24 ( 25 select isnull(UnSatisfaction.Subject_Name,T2.Subject_Name )as Subject_Name, isnull (UnSatisfaction.UnSatisfaction_Count,0) as UnSatisfaction_Count, T2.Satisfaction_Count, T2.BSatisfaction_Count, T2.General_Count From (SELECT [Subject].Subject_Name as Subject_Name, count(Survey_Answer.ID) as UnSatisfaction_Count 26 from Student,VClass,Survey_Answer,[Subject],Survey,Survey_Question 27 where VClass.VClass_Subject=[Subject].Subject_Id and VClass.VClass_Id=Student.Student_VClass and Survey_Answer.Student_No=Student.Student_No and Survey_Answer.Student_No=Student.Student_No and Survey.ID=Survey_Question.Survey_ID and Survey_Question.ID=Survey_Answer.SQ_Id and VClass.VClass_Years='2013' and Survey.ID=1 and A_Content='不滿意' Group by Subject_Name 28 ) as UnSatisfaction 29 ------------------------T2 30 Right join 31 ( 32 Select isnull(General. Subject_Name,T1.Subject_Name )as Subject_Name, isnull (General.General_Count,0) as General_Count, T1.Satisfaction_Count, T1.BSatisfaction_Count 33 From ( 34 SELECT [Subject].Subject_Name as Subject_Name, count(Survey_Answer.ID) as General_Count 35 from Student,VClass,Survey_Answer,[Subject],Survey,Survey_Question 36 where VClass.VClass_Subject=[Subject].Subject_Id and VClass.VClass_Id=Student.Student_VClass and Survey_Answer.Student_No=Student.Student_No and Survey_Answer.Student_No=Student.Student_No and Survey.ID=Survey_Question.Survey_ID and Survey_Question.ID=Survey_Answer.SQ_Id and VClass.VClass_Years='2013' and Survey.ID=1 and A_Content='一般' Group by Subject_Name 37 ) as General 38 39 40 -------------------------T1 41 right join 42 ( 43 select isnull(BSatisfaction.BSatisfaction_Count,0) as BSatisfaction_Count, isnull(Satisfaction. Satisfaction_Count,0) as Satisfaction_Count, isnull(Satisfaction. Subject_Name,BSatisfaction.Subject_Name )as Subject_Name 44 from ( 45 SELECT [Subject].Subject_Name as Subject_Name, count(Survey_Answer.ID) as BSatisfaction_Count 46 from Student,VClass,Survey_Answer,[Subject],Survey,Survey_Question 47 where VClass.VClass_Subject=[Subject].Subject_Id and VClass.VClass_Id=Student.Student_VClass and Survey_Answer.Student_No=Student.Student_No and Survey_Answer.Student_No=Student.Student_No and Survey.ID=Survey_Question.Survey_ID and Survey_Question.ID=Survey_Answer.SQ_Id and VClass.VClass_Years='2013' and Survey.ID=1 and A_Content='基本滿意' Group by Subject_Name 48 ) as BSatisfaction 49 50 right join 51 ( 52 SELECT [Subject].Subject_Name as Subject_Name, count(Survey_Answer.ID) as Satisfaction_Count 53 from Student,VClass,Survey_Answer,[Subject],Survey,Survey_Question 54 where VClass.VClass_Subject=[Subject].Subject_Id and VClass.VClass_Id=Student.Student_VClass and Survey_Answer.Student_No=Student.Student_No and Survey_Answer.Student_No=Student.Student_No and Survey.ID=Survey_Question.Survey_ID and Survey_Question.ID=Survey_Answer.SQ_Id and VClass.VClass_Years='2013' and Survey.ID=1 and A_Content='滿意' Group by Subject_Name 55 ) as Satisfaction 56 57 on Satisfaction.Subject_Name=BSatisfaction.Subject_Name )as T1 58 ------------------------------T1end 59 60 on T1.Subject_Name=General.Subject_Name )as T2 61 -----------------------------T2END 62 63 on T2.Subject_Name=UnSatisfaction.Subject_Name )As T3 64 65 ---------------------------------t3end 66 67 ON T3.Subject_Name=Survey.Subject_Name )As T4 68 69 -------------------------t4end 70 ON T4.Subject_Name=[Subject].Subject_Name )as T5 71 -------------------------t5end 72 on T5.Faculty_Id=T6.Faculty_Id
------------華麗的分割線-------------
新SQL完整語句

1 select Faculty_Name,T1.Subject_Name,Survey_Count, UnSatisfaction_Count,BSatisfaction_Count ,Satisfaction_Count ,General_Count , 2 isnull((Satisfaction_Count+BSatisfaction_Count)*1.0/nullif(General_Count+BSatisfaction_Count+UnSatisfaction_Count+Satisfaction_Count,0),0) as lastinfo 3 from ( 4 select [Subject].Subject_Name ,isnull(Survey_Count,0)as Survey_Count 5 from [Subject] 6 left join 7 8 (select [Subject].Subject_Name as Subject_Name, 9 count(DISTINCT Survey_Answer.Student_No) as Survey_Count 10 from Student,VClass,[Subject],Survey_Answer,Survey,Survey_Question 11 where VClass.VClass_Subject=[Subject].Subject_Id and VClass.VClass_Id=Student.Student_VClass 12 and Survey.ID=Survey_Question.Survey_ID and Survey_Question.ID=Survey_Answer.SQ_Id 13 and Survey_Answer.Student_No=Student.Student_No and VClass.VClass_Years='2013' 14 and Survey.ID=1 Group by [Subject].Subject_Name )as T1 15 on T1.Subject_Name=[Subject].Subject_Name 16 )as T1, 17 18 19 (select [Subject].Subject_Name ,isnull(UnSatisfaction_Count,0) as UnSatisfaction_Count 20 from [Subject] 21 left join 22 (SELECT [Subject].Subject_Name as Subject_Name, count(Survey_Answer.ID) 23 as UnSatisfaction_Count from Student,VClass,Survey_Answer,[Subject],Survey,Survey_Question 24 where VClass.VClass_Subject=[Subject].Subject_Id and VClass.VClass_Id=Student.Student_VClass 25 and Survey_Answer.Student_No=Student.Student_No and Survey_Answer.Student_No=Student.Student_No 26 and Survey.ID=Survey_Question.Survey_ID and Survey_Question.ID=Survey_Answer.SQ_Id 27 and VClass.VClass_Years='2013' and Survey.ID=1 and A_Content='不滿意' 28 Group by Subject_Name)as T1 29 on T1.Subject_Name=[Subject].Subject_Name 30 ) as T2, 31 32 33 (select [Subject].Subject_Name ,isnull(BSatisfaction_Count,0) as BSatisfaction_Count 34 from [Subject] 35 left join 36 (SELECT [Subject].Subject_Name as Subject_Name, count(Survey_Answer.ID) 37 as BSatisfaction_Count from Student,VClass,Survey_Answer,[Subject],Survey,Survey_Question 38 where VClass.VClass_Subject=[Subject].Subject_Id and VClass.VClass_Id=Student.Student_VClass 39 and Survey_Answer.Student_No=Student.Student_No and Survey_Answer.Student_No=Student.Student_No 40 and Survey.ID=Survey_Question.Survey_ID and Survey_Question.ID=Survey_Answer.SQ_Id 41 and VClass.VClass_Years='2013' and Survey.ID=1 and A_Content='基本滿意' 42 Group by Subject_Name )as T1 43 on T1.Subject_Name=[Subject].Subject_Name 44 )as T3, 45 46 47 48 (select [Subject].Subject_Name ,isnull(Satisfaction_Count,0) as Satisfaction_Count 49 from [Subject] 50 left join 51 (SELECT [Subject].Subject_Name 52 as Subject_Name, count(Survey_Answer.ID) as Satisfaction_Count 53 from Student,VClass,Survey_Answer,[Subject],Survey,Survey_Question 54 where VClass.VClass_Subject=[Subject].Subject_Id and VClass.VClass_Id=Student.Student_VClass 55 and Survey_Answer.Student_No=Student.Student_No and Survey_Answer.Student_No=Student.Student_No 56 and Survey.ID=Survey_Question.Survey_ID and Survey_Question.ID=Survey_Answer.SQ_Id 57 and VClass.VClass_Years='2013' and Survey.ID=1 and A_Content='滿意' Group by Subject_Name )as T1 58 on T1.Subject_Name=[Subject].Subject_Name 59 60 )as T4, 61 62 63 64 (select [Subject].Subject_Name ,isnull(General_Count,0) as General_Count 65 from [Subject] 66 left join 67 (SELECT [Subject].Subject_Name as Subject_Name, count(Survey_Answer.ID) 68 as General_Count from Student,VClass,Survey_Answer,[Subject],Survey,Survey_Question 69 where VClass.VClass_Subject=[Subject].Subject_Id and VClass.VClass_Id=Student.Student_VClass 70 and Survey_Answer.Student_No=Student.Student_No and Survey_Answer.Student_No=Student.Student_No 71 and Survey.ID=Survey_Question.Survey_ID and Survey_Question.ID=Survey_Answer.SQ_Id 72 and VClass.VClass_Years='2013' and Survey.ID=1 and A_Content='一般' Group by Subject_Name 73 )as T1 74 75 on T1.Subject_Name=[Subject].Subject_Name 76 77 )as T5, 78 (select Faculty.Faculty_Name ,Subject_Name 79 from [Subject],Faculty 80 where Faculty.Faculty_Id =[Subject].Subject_Faculty)as T6 81 82 83 where T6.Subject_Name=T1.Subject_Name and 84 T6.Subject_Name=T2.Subject_Name and 85 T6.Subject_Name=T3.Subject_Name and 86 T6.Subject_Name=T4.Subject_Name and 87 T6.Subject_Name=T5.Subject_Name
后記:
問卷調查使用一周后 已經有2300人填寫過了
下面附帶一些統計的效果圖