什麼時候在 MySQL 中使用視圖?
從多個連接創建用於分析的表時,何時更傾向於使用視圖而不是創建新表?
我更喜歡使用視圖的一個原因是數據庫模式是由我們的管理員在 Ruby 中開發的,而我對 Ruby 並不熟悉。我可以請求創建表,但需要一個額外的步驟,並且我希望在開發/測試新聯接時具有更大的靈活性。
我在回答有關 SO(何時使用 R,何時使用 SQL)的相關問題後開始使用視圖。票數最高的答案開始於“在 SQL 中進行數據操作,直到數據位於單個表中,然後在 R 中完成其餘部分。”
我已經開始使用視圖,但我遇到了一些視圖問題:
- 查詢要慢得多
- 視圖不會從生產數據庫轉儲到我用於分析的備份數據庫。
視圖是否適合這種用途?如果是這樣,我應該期待性能損失嗎?有沒有辦法加快對視圖的查詢?
MySQL 中的視圖是使用兩種不同算法之一處理的:
MERGE
或TEMPTABLE
.MERGE
只是一個帶有適當別名的查詢擴展。TEMPTABLE
就像聽起來一樣,視圖在執行 WHERE 子句之前將結果放入臨時表中,並且上面沒有索引。“第三個”選項是
UNDEFINED
,它告訴 MySQL 選擇適當的算法。MySQL 會嘗試使用MERGE
,因為它更高效。主要警告:如果不能使用 MERGE 算法,則必須使用臨時表。如果視圖包含以下任何構造,則不能使用 MERGE:
- 聚合函式(SUM()、MIN()、MAX()、COUNT() 等)
- 清楚的
- 通過…分組
- 擁有
- 限制
- UNION 或 UNION ALL
- 選擇列表中的子查詢
- 僅指文字值(在這種情況下,沒有基礎表)
我冒昧地猜測您的 VIEWS 需要 TEMPTABLE 算法,從而導致性能問題。
這是一篇關於 MySQL 中視圖性能的非常古老的部落格文章,它似乎並沒有變得更好。
然而,對於這個臨時表不包含索引(導致全表掃描)的問題,隧道盡頭可能會有一些啟示。在5.6中:
對於 FROM 子句中的子查詢需要物化的情況,優化器可以通過向物化表添加索引來加快對結果的訪問。…添加索引後,優化器可以將物化派生表視為與具有索引的普通表相同,並且從生成的索引中受益類似。與沒有索引的查詢執行成本相比,索引創建的成本可以忽略不計。
正如@ypercube 指出的那樣,MariaDB 5.3 添加了相同的優化。這篇文章對這個過程有一個有趣的概述:
應用了優化,然後派生表無法合併到其父 SELECT 中,當派生表不符合可合併視圖的條件時會發生這種情況