用 SQL Server 2000 索引檢視表提高效能

來源:互聯網
上載者:User
server|視圖|索引|效能

什麼是索引檢視表?

許多年來,Microsoft® SQL Server™ 一直都提供建立虛擬表(稱為視圖)的功能。在過去,這些視圖主要有兩種用途:

提供安全機制,將使用者限制在一個或多個基表中的資料的某個子集。
提供一種機制,允許開發人員定製使用者如何才能以邏輯方式查看儲存在基表中的資料。
SQL Server 2000 已經擴充了 SQL Server 視圖的功能,以提高系統效能。它可以在一個視圖上建立唯一的群集索引和非群集索引,可以改進最複雜查詢的資料訪問效能。在 SQL Server 2000 中,擁有唯一群集索引的視圖被稱為索引檢視表。

注意:   索引檢視表只是 SQL Server 2000 企業版和 SQL Server 2000 開發人員版的一個功能。

從資料庫管理系統 (DBMS) 的觀點來看,視圖是資料(中繼資料)的說明。建立典型視圖時,通過 SELECT 語句(定義一個顯示為虛擬表的結果集)來定義中繼資料。當其它查詢的 FROM 子句中引用了某個視圖時,將從系統目錄中檢索該中繼資料,並對其進行擴充以代替該視圖的引用。在視圖擴充之後,查詢最佳化工具會為正在執行的查詢編譯單個執行計畫。

如果是非索引檢視表,視圖在運行時將被實體化。任何計算(如聯結或彙總)都在為每個引用該視圖的查詢執行查詢期間進行。(視圖並不總需要被完全實體化。查詢可以包含其它一些謂詞、聯結或彙總,以應用於該視圖所引用的表和視圖。)在視圖上建立了唯一的群集索引之後,視圖的結果集會立即被實體化並持續儲存在資料庫的實體儲存體空間中,以便節省這種操作所佔用的大量資源。

在執行查詢時,有兩種方法可以使用索引檢視表。查詢可直接引用索引檢視表,更重要的是,如果查詢最佳化工具確定視圖能夠替換為查詢的部分或全部,而且這是低成本的查詢計劃,則可以選擇索引檢視表。第二種情況是使用索引檢視表代替基礎資料表及其普通索引。此時,不需要在查詢中引用視圖,查詢最佳化工具即可在執行查詢期間使用該視圖。這樣,現有的應用程式無需更改即可從建立的索引檢視表中獲益。


通過索引檢視表提高的效能

使用索引來提高查詢效能並不是什麼新觀念,不過,索引檢視表還具有使用標準索引不能獲得的其它效能優點。索引檢視表能夠在以下方面提高查詢效能:

能夠預先計算彙總並將其儲存在索引中,從而最大限度地減少在執行查詢期間進行成本很高的計算。
能夠預先聯結表並儲存產生的資料集。
能夠儲存聯結或彙總的組合。
下圖說明了查詢最佳化工具使用索引檢視表時一般能夠提高多少效能。提供的查詢複雜程度各不相同(例如,彙總計算的數量、所用表的數量或謂詞數),並包括來自實際生產環境的數百萬行的大表。

圖 1. 當查詢最佳化工具使用索引檢視表時一般能夠提高多少效能

使用視圖的輔助索引

視圖的輔助性非群集索引可以提高其它查詢效能。與表的輔助索引類似,視圖的輔助索引也可以提供更多選項,以便查詢最佳化工具在編譯過程中從中進行選擇。例如,如果查詢包括群集索引未涉及的列,最佳化器可以在計劃中選擇一個或多個輔助索引,從而避免對索引檢視表或基表進行費時的全域掃描。

由於索引需要不斷維護,所以為架構添加索引會增加資料庫的額外開銷。因此應該認真考慮,找到索引和維護額外開銷之間的平衡點。


使用索引檢視表的好處

實現索引檢視表之前,請先分析資料庫的工作量。運用自己對查詢以及各種工具(例如 SQL 分析器)的知識來鑒別使用索引檢視表可以獲益的查詢。如果經常進行彙總和聯結,最好使用索引檢視表。

並非所有查詢都會從索引檢視表中獲益。與普通索引類似,如果未使用索引檢視表,就沒有好處可言。在此情況下,不但不能提高效能,還會加大磁碟空間的佔用、增加維護和最佳化的成本。但是,如果使用了索引檢視表,它們可以(成數量級地)明顯地提高資料訪問的效能。這是因為查詢最佳化工具使用儲存在索引檢視表中的預先計算的結果,從而大大降低了執行查詢的成本。

查詢最佳化工具只在查詢的成本比較大時才考慮使用索引檢視表。這樣可以避免在查詢最佳化成本超出因使用索引檢視表而節省的成本時,試圖使用各種索引檢視表。當查詢成本低於 1 時,幾乎不使用索引檢視表。

使用索引檢視表可以受益的應用程式套件括:

決定支援工作量
資料集市
線上分析處理 (OLAP) 庫和源
資料採礦工作量
從查詢的類型和模式的角度來看,受益的應用可被歸納為包含以下內容的應用:

大表的聯結和彙總
查詢的重複模式
重複彙總相同或重疊的列集
針對相同關鍵字重複聯結相同的表
上述的組合
相反,包含許多寫入的聯機交易處理 (OLTP) 系統或更新頻繁的資料庫,可能會因為要同時更新視圖和根本基表而使維護成本增加,所以不能利用索引檢視表。


查詢最佳化工具如何使用索引檢視表

SQL Server 查詢最佳化工具可自動確定何時可以將索引檢視表用於給定的查詢執行中。查詢中無需直接引用視圖,最佳化器就可以將該視圖用於查詢執行計畫。因此,無需對現有的應用程式本身進行任何更改,這些應用程式即可利用索引檢視表。唯一需要做的就是建立索引檢視表。

最佳化器的考慮因素

查詢最佳化工具會考慮幾個條件來確定索引檢視表能涵蓋部分查詢還是整個查詢。這些條件符合查詢中的單個 FROM 子句並包含以下內容:

查詢 FROM 子句中的表必須是索引檢視表 FROM 子句中的表的超集。
查詢中的聯結條件必須是視圖中聯結條件的超集。
查詢中的彙總列必須是視圖中的彙總列的子集。
查詢挑選清單中的所有運算式都必須源自於視圖挑選清單或源自於不包括在視圖定義中的表。
查詢搜尋條件謂詞必須是視圖定義中搜尋條件謂詞的超集。視圖搜尋謂詞中的每個合取項都必須以同樣的形式出現在查詢搜尋謂詞中。
查詢搜尋條件謂詞中的所有列(屬於視圖定義中的表)都必須出現在下列一項或多項中:
視圖定義中的同一個謂詞。
GROUP BY 列表。
視圖挑選清單(若沒有 GROUP BY 列表)。
如果查詢包含多個 FROM 子句(子查詢、派生表、UNION),最佳化器可以選擇多個索引檢視表來管理含有多個 FROM 子句的查詢。

注意:   也存在例外情形,即最佳化器可能將兩個 FROM 子句摺疊成一個(將子查詢摺疊成聯結或將派生表摺疊成聯結變體)。如果出現此類情況,索引檢視表替換可能會涵蓋原查詢中的多個 FROM 子句。

本文檔結尾介紹了示範這些條件的查詢樣本。而建議的最佳方法就是:讓查詢最佳化工具來確定在查詢執行計畫中使用哪些索引(如果有的話)。

使用 NOEXPAND 選項

NOEXPAND 選項強制查詢最佳化工具象對待包含群集索引的普通表一樣對待視圖。在此情況下,必須在 FROM 子句中直接引用索引檢視表。例如:

SELECT Column1, Column2, ... FROM Table1, View1 WITH (NOEXPAND)WHERE ...

使用 EXPAND VIEWS 選項

另外,使用者可以在查詢結束時通過使用 EXPAND VIEWS 選項,明確地將索引檢視表排除在考慮之外。例如:

SELECT Column1, Column2, ... FROM Table1, View1 WHERE ...OPTION (EXPAND VIEWS)

如果使用該選項,查詢最佳化工具在評估低成本的方法(該方法涉及查詢中引用的列)時將忽略所有視圖索引。


設計的考慮因素

為資料庫系統找到適當的索引集是相當複雜的。儘管在設計普通索引時要考慮許多可能性,但將索引檢視表添加到架構會極大地增加設計和潛在結果的複雜性。例如,索引檢視表可用於:

查詢中所參考資料表的任何子集。
查詢中條件的任何子集(屬於表的上述子集)
分組列。
彙總函式,如 SUM。
應同時設計表的索引和索引檢視表,以便從各個結構中獲得最佳結果。由於索引和索引檢視表都可能對給定的查詢有用,所以單獨設計它們會導致多餘的建議方案,以致儲存和維護開銷較高。在調整資料庫的實體設計時,必須均衡考慮各種查詢集的效能要求與資料庫系統必須支援的更新操作。因此,為索引檢視表找到一種合理的實體設計是一項很具挑戰性的任務,因而應該儘可能地使用“索引微調嚮導”。

如果存在許多索引檢視表可供查詢最佳化工具考慮用於特定查詢,查詢最佳化成本會顯著增加。查詢最佳化工具可能考慮為查詢中表的任意子集定義的所有索引檢視表。拒絕每一個視圖之前,必須對它進行文法分析,然後研究其是否可能成為潛在的替換體。這可能需要一些時間,尤其是在有數百個此類的視圖用於給定的查詢時。

視圖必須符合幾項要求,您才能為其建立唯一的群集索引。在設計階段,請考慮以下要求:

視圖以及視圖中引用的所有表都必須在同一資料庫中,並具有同一個所有者。
索引檢視表無需包含要供最佳化器使用的查詢中引用的所有表。
必須先為視圖建立唯一群集索引,然後才可以建立其它索引。
建立基表、視圖和索引以及修改基表和視圖中的資料時,必須正確設定某些 SET 選項(在本文檔的後文中討論)。另外,如果這些 SET 選項正確,查詢最佳化工具將不考慮索引檢視表。
視圖必須使用架構綁定建立,視圖中引用的任何使用者定義的函數必須使用 SCHEMABINDING 選項建立。
另外,還要求有一定的磁碟空間來存放由索引檢視表定義的資料。

設計準則

設計索引檢視表時,請考慮以下準則:

設計的索引檢視表必須能用於多個查詢或多個計算。
例如,包含某列的 SUM 和某列的 COUNT_BIG 的索引檢視表可用於包含函數 SUM、COUNT、COUNT_BIG 或 AVG 的查詢。由於只需檢索視圖中的少數幾行,而不是基表中的所有行,且執行 AVG 函數要求的部分計算已經完成,所以查詢將比較快。

使索引保持緊湊。
通過使用最少的列數和儘可能少的位元組數,最佳化器在尋找行資料時可獲得最高的效率。相反,如果定義了大的群集索引關鍵字,則為視圖定義的任何輔助性非群集索引都將明顯增大,這是因為非群集索引項目除包含索引定義的列之外,還將包含群集關鍵字。

考慮產生的索引檢視表的大小。
在單純的彙總情況下,如果索引檢視表的大小類似於原表的大小,使用索引檢視表可能無法明顯提高任何效能。

設計多個較小的索引檢視表來加快部分進程的速度。
有時可能無法設計出能滿足整個查詢需要的索引檢視表。此時即可考慮建立這樣一些索引檢視表,每個索引檢視表執行一部分查詢。

考慮以下樣本:

經常執行的查詢會彙總一個資料庫中的資料,再彙總另一個資料庫中的資料,然後聯結結果。由於索引檢視表不能引用多個資料庫中的表,所以您不能設計一個視圖來執行整個進程。不過,可以為要進行彙總的每個資料庫建立索引檢視表。如果最佳化器能夠將索引檢視表與常設查詢相匹配,至少彙總處理將會因為不必記錄常設查詢而提高速度。儘管聯結處理不會加快,整個查詢的速度卻因使用了儲存在索引檢視表中的彙總而加快。
經常執行的查詢會彙總多個表中的資料,然後使用 UNION 來將結果結合起來。UNION 不允許在索引檢視表中使用。您可以設計一些視圖來執行每個單獨的彙總運算。然後最佳化器可以選擇索引檢視表來加快查詢的速度,而無需記錄查詢。儘管 UNION 處理沒有改進,單個彙總進程卻得以改進。

使用“索引微調嚮導”

“索引微調嚮導”除建議使用基表的索引之外,還建議使用索引檢視表。使用該嚮導可提高管理員確定索引和索引檢視表相結合的能力,從而最佳化針對資料庫執行的典型混合查詢的效能。

由於“索引微調嚮導”強制使用所有必需的 SET 選項(以確保結果集的正確性),其索引檢視表將會成功建立。不過,如果您的應用程式的選項沒有按照要求設定,可能無法利用這些視圖。對那些參與索引檢視表定義的表執行的插入、更新或刪除操作可能會失敗。


維護索引檢視表

SQL Server 自動維護索引檢視表,這與維護任何其它索引的情況類似。對於普通索引而言,每個索引都直接連接到單個表。通過對基礎資料表執行每個 INSERT、UPDATE 或 DELETE 操作,索引相應地進行了更新,以便使儲存在該索引中的值始終與表一致。

索引檢視表的維護與此類似。不過,如果視圖引用了多個表,則對這些表中的任何一個進行更新都需要更新索引檢視表。與普通索引不同的是,對任何一個參與的表執行一次行插入操作都可能導致在索引檢視表中進行多次行插入操作。更新和刪除操作的情況也是如此。因此,較之於維護表的索引,維護索引檢視表的代價更為高昂。

在 SQL Server 2000 中,某些視圖可以更新。如果某個視圖可以更新,則使用 INSERT、UPDATE 和 DELETE 語句可通過該視圖直接修改根本基表。為某個視圖建立索引並不會妨礙該視圖的更新。有關可更新視圖的詳細資料,請參閱關於 SQL Server 2000 的“SQL Server 聯機圖書”中的“通過視圖修改資料(英文)”。

維護成本的考慮因素

設計索引檢視表時應該考慮以下幾點:

資料庫中需要有一個額外的儲存空間用於索引檢視表。索引檢視表的結果集以類似於典型表格儲存體空間的方式物理儲存在資料庫中。
SQL Server 自動維護視圖。因此,對定義視圖所據的基表的任何更改都可能引起視圖索引的一處或多處更改,從而導致維護開銷的增加。
一個視圖獲得的淨效能提高就是視圖提供的查詢執行節約總計與儲存和維護該視圖耗費的成本之間的差。

估計視圖將佔用的所需儲存空間要相對簡單一些。用 SQL 查詢分析器的“顯示估計的執行計畫”工具求視圖定義中 SELECT 語句的值。該工具將得出查詢返回的行數和行大小的近似值。將這兩個值相乘,即可估計出視圖的可能大小。不過這隻是一個近似值。視圖索引的實際大小隻能通過建立視圖索引來精確得出。

從 SQL Server 執行的自動維護考慮因素的觀點出發,“顯示估計的執行計畫”的功能可能會對此開銷的影響有所瞭解。如果用 SQL 查詢分析器評估修改視圖的語句(針對視圖的 UPDATE 語句、針對基表的 INSERT 語句),SHOWPLAN 將包括該語句的維護操作。同時考慮此成本和此操作將在生產環境中發生的次數,可以指示視圖維護的可能成本。

通常建議對視圖或基表進行的任何修改和更新都應該儘可能地成批執行,而不要單獨進行。這樣可以減少視圖維護的某些開銷。


建立索引檢視表

建立索引檢視表所需的步驟與視圖的成功實現密不可分。

確保將在視圖中引用的所有現有表的 SET 選項都正確。
建立任何新表和視圖之前,確保會話的 SET 選項已正確設定。
確保視圖定義是確定的。
使用 WITH SCHEMABINDING 選項建立視圖。
建立視圖的唯一群集索引。

使用 SET 選項以獲得一致的結果

如果在執行查詢時啟用不同的 SET 選項,則在 SQL Server 中對同一個運算式求值會產生不同的結果。例如,將 SET 選項 CONCAT_NULL_YIELDS_NULL 設定為 ON 之後,運算式 'abc' + NULL 返回的值是 NULL。而將 CONCAT_NULL_YIEDS_NULL 設定為 OFF 之後,該運算式得出的結果卻是 'abc'。索引檢視表要求多個 SET 選項的值都固定,以確保這些視圖能夠得到正確維護並返回一致的結果。

只要出現以下情況,就必須將下表中的 SET 選項設定為要求的值列中所示的值:

建立了索引檢視表。
對索引檢視表中引用的任何錶執行了任何 INSERT、UPDATE 或 DELETE 操作。
查詢最佳化工具使用索引檢視表來產生查詢計劃。
SET
選項 要求
的值 預設
伺服器
的值 OLE DB

ODBC 的值 DB LIB
的值
ANSI_NULLS ON OFF ON OFF
ANSI_PADDING ON ON ON OFF
ANSI_WARNING ON OFF ON OFF
ARITHABORT ON OFF OFF OFF
CONCAT_NULL_YIELDS_NULL ON OFF ON OFF
NUMERIC_ROUNDABORT OFF OFF OFF OFF
QUOTED_IDENTIFIER ON OFF ON OFF


如果使用的是 OLE DB 或 ODBC 伺服器串連,唯一必須修改的值是 ARITHABORT 的設定。所有 DB LIB 值都必須使用 sp_configure 在伺服器級上正確設定或使用 SET 命令從應用程式正確設定。有關 SET 選項的詳細資料,請參閱關於 SQL Server 2000 的“SQL Server 聯機圖書”中的“使用 SQL Server 中的選項(英文)”。


使用確定性函數

索引檢視表的定義必須是確定性。如果挑選清單中的所有運算式以及 WHERE 和 GROUP BY 子句都是確定性,則視圖就是確定性。只要用特定的一組輸入值對確定性運算式進行求值,一定會返回同一個結果。只有確定性函數可以加入確定性運算式。例如,DATEADD 是確定性函數,因為將任何給定的一組變數值賦予它的三個參數進行求值,返回的總是同一個結果。而 GETDATE 則不是確定性函數,因為始終用同一個變數調用它,而它每次執行後返回的值都不相同。有關詳細資料,請參閱關於 SQL Server 2000 的“SQL Server 聯機圖書”中的“確定性和非確定性函數”。

即便某個運算式是確定性,但如果其中包含浮動運算式,確切的結果就可能取決於處理器的體繫結構或微代碼的版本。要確保 SQL Server 2000 中資料的完整性,此類運算式只能加入索引檢視表的非關鍵列。不包含浮動運算式的確定性運算式被稱為精確的運算式。只有精確的確定性運算式可以加入索引檢視表的關鍵列和 WHERE 或 GROUP BY 子句。

使用 COLUMNPROPERTY 函數和 IsDeterministic 屬性來確定視圖列是否是確定性。使用 COLUMNPROPERTY 函數和 IsPrecise 屬性來確定包含架構綁定的視圖中的確定性列是否是精確的。如果為 TRUE,則 COLUMNPROPERTY 會返回 1,如果為 FALSE,則返回 0,如果是無效的輸入(列不是確定性),則返回 NULL。例如,SELECT COLUMNPROPERTY(Object_Id('Vdiscount1'),'SumDiscountPrice','IsPrecise') 返回的是 0,因為 SumDiscountPrice 列引用了表 Order Details 中的浮動列 Discount。而同一視圖中的列 SumPrice 既是確定性又是精確的。

注意:   該 SELECT 語句所基於的視圖能夠在樣本部分找到(視圖 1)。


其它要求

除“設計準則”、“使用 SET 選項以獲得一致的結果”和“使用確定性函數”部分中列出的要求之外,還必須符合以下要求。

基表要求

基表在建立時必須正確設定 SET 選項,否則就不能被包含架構綁定的視圖引用。
表必須通過視圖定義中的兩部分名稱(所有者.表名)引用。
函數要求

使用者定義的函數必須使用 WITH SCHEMABINDING 選項建立。
使用者定義的函數必須通過兩部分名稱(所有者.函數)引用。
視圖要求

視圖必須使用 WITH SCHEMABINDING 選項建立。
視圖必須只引用同一資料庫中的基表,而不能引用其它視圖。
文法限制

對視圖定義的文法有幾個限制。視圖定義不能包含以下內容:

COUNT(*)
ROWSET 函數
派生表
自我聯結
DISTINCT
STDEV、VARIANCE、AVG
Float* 列、文本列、ntext 列、映像列
子查詢
全文謂詞(CONTAIN、FREETEXT)
可空運算式的 SUM
MIN、MAX
TOP
OUTER 聯結
UNION
注意:   索引檢視表可以包含浮動列,不過,此類列不能包含在群集索引關鍵字中。

GROUP BY 限制

如果未使用 GROUP BY,運算式不能在挑選清單中使用。

如果使用了 GROUP BY,則 VIEW 定義:

必須包含 COUNT_BIG(*)。
不得包含 HAVING、CUBE 或 ROLLUP。
這些限制只適用於索引檢視表定義。查詢可以在其執行計畫中使用索引檢視表,即便該索引檢視表並不符合這些 GROUP BY 限制。

索引要求

執行 CREATE INDEX 語句的使用者必須是視圖所有者。
如果視圖定義中包含 GROUP BY 子句,唯一群集索引的關鍵字只能引用 GROUP BY 子句中指定的列。

樣本

本部分的樣本闡述索引檢視表在兩種主要查詢(彙總和聯結)中的使用問題。同時還說明查詢最佳化工具在確定某個索引檢視表是否可用時使用的條件。有關這些條件的完整列表,請參閱查詢最佳化工具如何使用索引檢視表。

查詢基於 Northwind(SQL Server 2000 中提供的資料庫樣本)中的表,並可以寫入的方式執行。建立視圖的前後,最好使用 SQL 查詢最佳化工具中的“顯示執行計畫”工具來查看查詢最佳化工具選定的計劃。儘管樣本中闡述了最佳化器是如何選擇成本最低的執行計畫的,但因為 Northwind 資料庫樣本太小,因此無法體現效能的提高。

以下查詢顯示如何從 Order Details 表中返回具有最大總折扣的五種產品的兩個方法。

查詢 1

SELECT TOP 5 ProductID, SUM(UnitPrice*Quantity) -
SUM(UnitPrice*Quantity*(1.00-Discount))AS Rebate
FROM [Order Details]
GROUP BY ProductID
ORDER BY Rebate DESC

查詢 2

SELECT TOP 5 ProductID, SUM(UnitPrice*Quantity*Discount)AS Rebate
FROM [Order Details]
GROUP BY ProductID
ORDER BY Rebate DESC

查詢最佳化工具選定的執行計畫包含:

對 Order Details 表的群集索引掃描,估計有 2,155 行。
雜湊匹配/彙總運算子,該運算子基於 GROUP BY 列將選定的行放入雜湊表,然後計算每行的 SUM 彙總。
基於 ORDER BY 子句的 TOP 5 排序運算子。
視圖 1

添加包括 Rebate 列所需彙總的索引檢視表將更改查詢 1 的查詢執行計畫。在數百萬行的大表上,查詢的效能也將明顯提高。

CREATE VIEW Vdiscount1 WITH SCHEMABINDING
AS
SELECT SUM(UnitPrice*Quantity)AS SumPrice,
SUM(UnitPrice*Quantity*(1.00-Discount))
AS SumDiscountPrice, COUNT_BIG(*) AS Count, ProductID
FROM dbo.[Order Details]
GROUP BY ProductID
   GO
CREATE UNIQUE CLUSTERED INDEX VDiscountInd ON Vdiscount1 (ProductID)

第一個查詢的執行計畫顯示 Vdiscount1 視圖由查詢最佳化工具使用。不過,由於該視圖不包含 SUM(UnitPrice*Quantity*Discount) 彙總,因此不會被第二個查詢使用。可以建立另一個可以同時滿足上述兩個查詢的索引檢視表。

視圖 2

CREATE VIEW Vdiscount2 WITH SCHEMABINDING
AS
SELECT SUM(UnitPrice*Quantity)AS SumPrice,
SUM(UnitPrice*Quantity*(1.00-Discount))AS SumDiscountPrice,
SUM(UnitPrice*Quantity*Discount)AS SumDiscountPrice2, COUNT_BIG(*)
AS Count, ProductID
FROM dbo.[Order Details]
GROUP BY ProductID
GO
CREATE UNIQUE CLUSTERED INDEX VDiscountInd ON Vdiscount2 (ProductID)

有了該索引檢視表,現在兩個查詢的查詢執行計畫包含:

對 Vdiscount2 視圖的群集索引掃描,估計有 77 行
基於 ORDER BY 子句的 TOP 5 排序函數
查詢最佳化工具選擇該視圖是因為它提供了最低的執行成本,儘管在查詢中並未引用該視圖。

查詢 3

查詢 3 類似於前幾個查詢,只是 ProductID 已被 OrderID 所取代,視圖定義中沒有包括該列。這違背了以下條件:查詢挑選清單中的所有運算式都必須能從未包括在視圖定義內的表的視圖挑選清單中派生。

SELECT TOP 3 OrderID, SUM(UnitPrice*Quantity*Discount) OrderRebate
FROM dbo.[Order Details]
GROUP BY OrderID
ORDER BY OrderRebate desc

要求單獨的索引檢視表來滿足該查詢。可以對 Vdiscount2 進行修改,使它包括 OrderID,但是所產生視圖的行數將與原表的行數相同,因此,提供的效能也不會高於使用基表所提供的效能。

查詢 4

該查詢可產生每個產品的平均價格。

SELECT ProductName, od.ProductID,
 AVG(od.UnitPrice*(1.00-Discount)) AS AvgPrice, SUM(od.Quantity) AS Units
FROM [Order Details] od, Products p
WHERE od.ProductID=p.ProductID
GROUP BY ProductName, od.ProductID

索引檢視表的定義中不能包括複雜的彙總(例如,STDEV、VARIANCE、AVG),不過,如果索引檢視表中包括幾個聯合起來執行複雜彙總的簡單彙總函式,即可用於執行包含 AVG 的查詢。

視圖 3

該索引檢視表包含執行 AVG 函數所需的簡單彙總函式。在建立了視圖 3 後執行查詢 4 時,執行計畫會顯示正被使用的視圖。最佳化器可以從視圖的簡單彙總列 Price 和 Count 和 Count 中匯出 AVG 運算式。

CREATE VIEW View3 WITH SCHEMABINDING
AS
SELECT ProductID, SUM(UnitPrice*(1.00-Discount))AS Price,
COUNT_BIG(*)AS Count, SUM(Quantity)AS Units
FROM dbo.[Order Details]
GROUP BY ProductID
Go
CREATE UNIQUE CLUSTERED INDEX iv3 ON View3 (ProductID)

查詢 5

該查詢與查詢 4 相同,只不過包括一個附加搜尋條件。即使該附加搜尋條件只引用未包括在視圖定義內的表中的列,視圖 3 也將用於該查詢。

SELECT ProductName, od.ProductID, AVG(od.UnitPrice*(1.00-Discount))
AS AvgPrice, SUM(od.Quantity)AS Units
FROM [Order Details] AS od, Products AS p
WHERE od.ProductID=p.ProductID
AND p.ProductName like '%Tofu%'
GROUP BY ProductName, od.ProductID

查詢 6

查詢最佳化工具不能將視圖 3 用於該查詢。附加搜尋條件 od.UnitPrice>10 包含視圖定義內的表中的列,而該列卻不出現在 GROUP BY 列表中,搜尋謂詞也不出現在視圖定義中。

SELECT ProductName, od.ProductID, AVG(od.UnitPrice*(1.00-Discount))
 AS AvgPrice, SUM(od.Quantity) AS Units
FROM [Order Details] od, Products p
WHERE od.ProductID = p.ProductID
AND od.UnitPrice > 10
GROUP BY ProductName, od.ProductID

查詢 7

相反,查詢最佳化工具可以將視圖 3 用於查詢 7,原因是新搜尋條件 od.ProductID in (1,2,13,41) 中定義的列包括在視圖定義內的 GROUP BY 子句中。

SELECT ProductName, od.ProductID, AVG(od.UnitPrice*(1.00-Discount))
AS AvgPrice, SUM(od.Quantity) AS Units
FROM [Order Details] AS od, Products AS p
WHERE od.ProductID = p.ProductID
AND od.ProductID in (1,2,13,41)
GROUP BY ProductName, od.ProductID

視圖 4

該視圖在視圖定義中包括了列 od.Discount,可以滿足查詢 6 的條件。

CREATE VIEW View4 WITH SCHEMABINDING
AS
SELECT ProductName, od.ProductID, SUM(od.UnitPrice*(1.00-Discount))
AS AvgPrice, SUM(od.Quantity) AS Units, COUNT_BIG(*) AS Count
FROM dbo.[Order Details] AS od, dbo.Products AS p
WHERE od.ProductID = p.ProductID
AND od.UnitPrice > 10
GROUP BY ProductName, od.ProductID
GO
CREATE UNIQUE CLUSTERED INDEX VdiscountInd on View4 (ProductName, ProductID)

查詢 8

視圖 4 的同一個索引還將用於一個添加了與表 Orders 的聯結的查詢。該查詢符合以下條件:查詢 FROM 子句中列出的表是索引檢視表的 FROM 子句中表的超集。

SELECT ProductName, od.ProductID, AVG(od.UnitPrice*(1.00-Discount))
AS AvgPrice, SUM(od.Quantity) AS Units
FROM dbo.[Order Details] AS od, dbo.Products AS p, dbo.Orders AS o
WHERE od.ProductID = p.ProductID and o.OrderID = od.OrderID
AND od.UnitPrice > 10
GROUP BY ProductName, od.ProductID

最後兩個查詢是查詢 8 的變體。每個變體都違背了一個最佳化器條件,因此與查詢 8 不同,不能使用視圖 4。

查詢 8a

由於視圖定義中的 UnitPrice > 10 與查詢中的 UnitPrice > 25 之間的 WHERE 子句不匹配,所以 Q8a 不能使用索引檢視表。查詢搜尋條件謂詞必須是視圖定義中搜尋條件謂詞的超集。

SELECT ProductName, od.ProductID, AVG(od.UnitPrice*(1.00-Discount)) AvgPrice,
SUM(od.Quantity) AS Units
FROM dbo.[Order Details] AS od, dbo.Products AS p, dbo.Orders AS o
WHERE od.ProductID = p.ProductID and o.OrderID = od.OrderID
AND od.UnitPrice > 25
GROUP BY ProductName, od.ProductID

查詢 8b

注意,表 Orders 沒有參與索引檢視表 V4 的定義。儘管如此,在該表中添加謂詞將禁止使用索引檢視表,原因是添加的謂詞可能會消除彙總中的其它行(如查詢 8b 中所示)。

SELECT ProductName, od.ProductID, AVG(od.UnitPrice*(1.00-Discount))
AS AvgPrice, SUM(od.Quantity) AS Units
FROM dbo.[Order Details] AS od, dbo.Products AS p, dbo.Orders AS o
WHERE od.ProductID = p.ProductID and o.OrderID = od.OrderID
AND od.UnitPrice > 10
AND o.OrderDate > '01/01/1998'
GROUP BY ProductName, od.ProductID


 



相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.