5.6.2 視圖對性能的影響

5.6.2  視圖對性能的影響

Performance Implications of Views

許多人都不認爲視圖可以改進性能,但是它確實可以提高性能,也可以用它來支持其他提高性能的方式。例如,利用視圖重構數據庫架構的某一階段,可以在更改它訪問的表的同時,使代碼繼續工作。

一些應用程序爲每一個用戶使用一個表,這通常是爲了實現行級別安全性。一個和前面例子類似的視圖能夠在表內實現類似的安全性,並且打開表的次數會更少,這有助於提高性能。被很多用戶使用的許多開源工程已經累積了上百萬張表,它們可以從這種方式得益。下面有一個假想的博客系統數據庫:

  1. CREATE VIEW blog_posts_for_user_1234 AS 
  2.     SELECT * FROM blog_posts WHERE user_id = 1234  
  3.     WITH CHECK OPTION;  

可以使用視圖實現列級權限,但是卻沒有實際創建這些權限的開銷。列級權限也會阻止查詢被緩存。視圖可以限制訪問想要的列,但卻不會導致這些問題:

  1. CREATE VIEW public.employeeinfo AS 
  2.     SELECT firstname, lastname -- but not socialsecuritynumber  
  3.     FROM private.employeeinfo;  
  4. GRANT SELECT ON public.* TO public_user; 

有時可以使用僞臨時視圖取得好的效果。這不用創建一個只在當前連接中存在的真正臨時視圖,而是用一種特殊的方式,比如在特定的數據庫中,創建一個視圖,在使用完之後就可以把它刪除。接下來就可以在FROM子句中使用這個視圖,就像在FROM子句中使用子查詢一樣。這兩種方式在理論上是一樣的,但是MySQL對視圖有不同的代碼庫(Codebase),所以通過臨時視圖可能會得到更好的性能。下面是一個例子:

  1. -- Assuming 1234 is the result of CONNECTION_ID( )  
  2. CREATE VIEW temp.cost_per_day_1234 AS 
  3.     SELECT DATE(ts) AS daysum(cost) AS cost  
  4.     FROM logs.cost  
  5. GROUP BY day;  
  6.  
  7. SELECT c.day, c.cost, s.sales  
  8. FROM temp.cost_per_day_1234 AS c  
  9. INNER JOIN sales.sales_per_day AS s USING(day);  
  10.  
  11. DROP VIEW temp.cost_per_day_1234; 

要注意到使用了連接ID作爲唯一的後綴,以避免名字衝突。這種方式在應用程序崩潰並無法刪除臨時視圖時可以比較方便地進行清理。請查看第394頁的"丟失的臨時表"瞭解更多細節。

使用了臨時表算法的視圖性能可能會很差(儘管它們比沒有使用視圖的同樣查詢性能會好一些)。MySQL在優化外部查詢的時候就使用遞歸的步驟執行了它,這時外部查詢的優化還沒有完成,所以它沒有得到完全的優化。構造臨時表的查詢不會從外部查詢中得到WHERE條件,並且臨時表沒有索引。下面仍然使用temp.cost_per_ day_1234舉一個例子:

  1. mysql> SELECT c.day, c.cost, s.sales  
  2.      -> FROM temp.cost_per_day_1234 AS c  
  3.      ->     INNER JOIN sales.sales_per_day AS s USING(day)  
  4.      ->     WHERE day BETWEEN '2007-01-01' AND '2007-01-31'

在服務器執行這個視圖,把結果放到臨時表,然後聯接sales_per_day表的過程中,到底發生了什麼呢?WHERE子句中的BETWEEN限制沒有被"推送"到視圖中,所以視圖會爲表中的所有日期創建結果,這不會有什麼問題,因爲服務器將會把臨時表排在聯接的第一位,所以聯接就可以使用sales_per_day表的索引。但是,如果將這樣的兩個視圖進行聯接,那麼就不會有任何索引的優化了。

如果想用視圖來提高性能,那麼總是要進行測試,至少也應該進行分析。甚至合併視圖也會增加開銷,並且很難預測視圖如何影響性能。如果有性能問題,永遠也不要猜測,一定要進行測量。

視圖引入了一些並非只有MySQL纔有的問題。視圖會誤導開發人員,認爲它非常簡單,但實際上它非常複雜。某些查詢看上去是反覆查詢一個表,但實際是查詢一個代價很高的視圖,一個不理解它潛在複雜性的開發人員會對這個現象無動於衷。我們曾經看到過一個很簡單的查詢在解釋器中輸出了上百條記錄,因爲其中某些表其實是視圖,而它們又引用了很多其他的表和視圖。

轉自:http://book.51cto.com/art/201001/181019.htm

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章