歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> Linux教程

Oracle不合理的表設結構計導致執行緩慢

收到開發這邊的確認請求,如下三個語句,執行計劃的COST均一樣,但為什麼實際執行效果相差很大(1)的查詢速度很慢,2)和3)都正常)。

 

    1. 1)  
    2. Select *  
    3. From (Select *  
    4.              From V_Question_Head Vquest0_  
    5.              Where 1 = 1   
    6.              Order By Vquest0_.State Asc, Vquest0_.Ask_Time Desc) Where Rownum <= 6;  
    7.  
    8. 2)  
    9. Select *  
    10.  
    11. From (Select *  
    12.              From V_Question_Head Vquest0_  
    13.              Where 1 = 1 And Rownum <= 6  
    14.              Order By Vquest0_.State Asc, Vquest0_.Ask_Time Desc);  
    15.  
    16. 3)  
    17. Select *  
    18. From (Select *  
    19.              From Question_Head Vquest0_  
    20.              Where 1 = 1   
    21.              Order By Vquest0_.State Asc, Vquest0_.Ask_Time Desc) Where Rownum <= 6; 

 

看如下執行計劃,顯然2速度快可以理解,因為行數只有6,而1和3為什麼有那麼大的速度差距,要命的是執行計劃看起來沒有差距。

  1. SELECT STATEMENT, GOAL = ALL_ROWS                                          Cost=1710    Cardinality=6    Bytes=27912 
  2.  COUNT STOPKEY                     
  3.   VIEW    Object owner=GAZA                                                Cost=1710    Cardinality=20237    Bytes=94142524 
  4.    SORT ORDER BY STOPKEY                                                   Cost=1710    Cardinality=20237    Bytes=5949678 
  5.     TABLE ACCESS FULL    Object owner=TEST    Object name=QUESTION_HEAD    Cost=421     Cardinality=20237    Bytes=5949678 
  6.  
  7.  
  8. SELECT STATEMENT, GOAL = ALL_ROWS                                          Cost=1710    Cardinality=6    Bytes=27912 
  9.  VIEW                    Object owner=TEST                                 Cost=1710    Cardinality=6    Bytes=27912 
  10.   SORT ORDER BY                                                            Cost=1710    Cardinality=6    Bytes=1764 
  11.    COUNT STOPKEY                     
  12.     TABLE ACCESS FULL    Object owner=TEST    Object name=QUESTION_HEAD    Cost=421     Cardinality=20237    Bytes=5949678 
  13.  
  14.  
  15. SELECT STATEMENT, GOAL = ALL_ROWS                                          Cost=1710    Cardinality=6    Bytes=28590 
  16.  COUNT STOPKEY                     
  17.   VIEW    Object owner=TEST                                                Cost=1710    Cardinality=20237    Bytes=96429305 
  18.    SORT ORDER BY STOPKEY                                                   Cost=1710    Cardinality=20237    Bytes=5949678 
  19.     TABLE ACCESS FULL    Object owner=TEST    Object name=QUESTION_HEAD    Cost=421     Cardinality=20237    Bytes=5949678 

初步看看,無非1是查視圖,3是直接查表的區別,但關鍵是去掉Order By Vquest0_.State Asc, Vquest0_.Ask_Time Desc後兩者的執行時間差不多,而加上排序後時間就有數十倍的差距,再來看看視圖V_Question_Head

  1. create or replace view v_question_head as
  2. Select t.Accept_Id, t.Industry_Id, t.Dept_Id, t.Title, t.Question, t.Requester, t.Requester_Name, t.Ask_Time, t.Answer, 
  3.              t.Answer_Man, t.Answer_Time, t.Is_Hot, t.Check_Man, t.Check_Time, t.Satisfaction, t.Satis_Reason, t.Telphone, 
  4.              t.Is_Display, t.Hot_Sort, t.Check_State, t.State, t.Bbs_Id, t.Acceptor, t.Accept_Time, t.Is_Anonymous, 
  5.              t.Anonymous_Email, t.Ip_Address, t.Is_Requester_Read, 
  6.              (Select Count(r1.Accept_Id) From Answer_Remind r1 Where t.Accept_Id = r1.Accept_Id) As Reminded_Count, 
  7.              (Select (Case 
  8.                                     When Count(r2.Accept_Id) > 0 Then 
  9.                                      1 
  10.                                     Else 
  11.                                      0 
  12.                                 End) 
  13.                  From Answer_Remind r2 
  14.                  Where t.Accept_Id = r2.Accept_Id) As Is_Reminded 
  15. From Question_Head t 
  16. Order By t.State Asc, t.Ask_Time Desc 

通過如上視圖,我們不難發現雖然執行計劃中沒有體現COUNT的代價,但其中有行級的COUNT,也就是主表有多少行就要COUNT多少次,而這時一個很恐怖的數字。顯然這是表結構設計上的問題。而要優化就是要更改表結構,在主表中及上需要COUNT的字段。

Copyright © Linux教程網 All Rights Reserved