2011-02-05 53 views
3

查詢視圖而不是存儲過程中的原始表是否是一種好的做法? (即使視圖不提供任何不同的數據)使用視圖而不是存儲過程中的表?

我總是覺得它可能是一個好主意,因爲它是一個額外的抽象層,它類似於在類函數中使用屬性而不是成員變量。

但是現在我正在查看由ASP.NET成員提供程序創建的存儲過程,並且它們總是直接對錶進行查詢。

我知道你不能輕鬆地插入數據時使用視圖,但如果存儲過程只查詢數據,你應該仍然直接使用表?如果是的話,主要原因是什麼? (性能?)

回答

6

視圖只是一個擴展到外部查詢的宏。

如果您的視圖包含多個連接,那麼當您連接到其他視圖時,如果實際在存儲過程的SQL中看到3個JOIN,您突然有20或30種方式JOIN。您還會發現每個查詢都是不同的:爲什麼每個查詢要連接相同的20或30個表?

一般來說,除非視圖被索引/實現並且優化器可以使用它,否則沒有任何好處。

諸如在一個視圖掩蓋的單個表上進行計算的想法應該在計算列中:爲什麼要繼續計算它?對於視圖中多個表格的計算,應對其進行索引。

使用存儲過程已經意味着沒有基表訪問(所有權鏈接)。

有意見很好的用途,以避免用戶直接訪問表,或掩蓋架構更改,或者提供一些基本的安全性(例如,基於SUSER_SNAME),而不是性能或期清初

3

不同的數據庫優化器以不同的方式優化查詢,所以它不是一個簡單的答案。但通常添加一個抽象層可以(不一定)停止優化器正確使用索引。

在SQL Server中,如果你有一個包含通話就像一個where子句:

  • IS NULL
  • LIKE '%的東西'
  • NOT EXISTS

它使一個non-sargable查詢,即不使用索引的查詢 - 或者以最佳方式使用它們。

我猜想使用視圖也會影響sarg。我會去測試這個(在Sql Server中) - 我會在5分鐘後回來。

編輯

我想,答案是「這取決於」那你需要打開,以確保您的查詢執行計劃,下面的測試,我沒有表現之間的查詢一個簡單的沒有什麼區別基於表查看並簡單地查詢基礎表。但它需要進一步測試,因爲複雜的觀點可能會有不同的表現

Sql Execution Plan for accessing a simple view compared to the table directly

+0

「我會去測試這個(在Sql Server中) - 我會在5分鐘後回來。」 - 哈,謝謝。我會在這裏等。 :D – magnattic 2011-02-05 15:52:43

0

我在這兩種情況下使用的視圖在存儲過程:

1 - 爲複雜的連接或中所需的多個程序

2條件 - 以substitue爲重命名的表。例如,我有兩個表,稱爲'成員'和'non_member'。我後來決定將這些結合到一個'用戶'表中。爲了避免修改我曾寫過的每個proc,我創建了一個名爲'member'和'non_member'的視圖,它使用where子句適當地過濾'user'表。所有procs都像以前一樣運行而不用更改。我有時間可以改變它們直接訪問新表格。

0

在SQL Server(至少),我的理解是,存儲過程在編譯時被優化,因此總體上比視圖更高效。我不確定,但我懷疑,通過針對某個視圖執行SPRC,您可能會失去通過這種方式獲得的任何優化。

此外,爲什麼?正如之前發佈的海報,如果您包含的一個或多個視圖本身由衆多聯接組成,那麼您可能會執行的聯接數量超過您的需要,而且這並不明顯。

此外,我的理解是,使用視圖的主要原因之一是以用戶可以使用的格式顯示錶數據,同時保護表數據免受無意的更改。由於SPROC的結果集不受INSERTS和UPDATES的限制,這一點是沒有意義的。

由於設計中的存儲過程接受參數,不允許用戶直接與表數據交互,並且可以執行任何可能在視圖中使用的查詢邏輯(加上更多),在我看來, (有一些例外),人們可能會這樣做的主要原因是爲了使編碼更容易,並且犧牲性能和可維護性(如果某人改變其中一個視圖,卻沒有意識到SPROC依賴它)呢?

我建議把它全部編碼到SPROC中,除非有一個令人信服的理由否則。 。 。

相關問題