SQL Server和Oracle數據庫索引介紹

  索引是與表或視圖關聯的磁盤上結構,可以加快從表或視圖中檢索行的速度。索引包含由表或視圖中的一列或多列生成的鍵。這些鍵存儲在一個結構(B 樹)中,使 SQL Server 可以快速有效地查找與鍵值關聯的行。

  表或視圖可以包含以下類型的索引:

  聚集索引

  聚集索引根據數據行的鍵值在表或視圖中排序和存儲這些數據行。索引定義中包含聚集索引列。每個表只能有一個聚集索引,因爲數據行本身只能按一個順序排序。

  只有當表包含聚集索引時,表中的數據行才按排序順序存儲。如果表具有聚集索引,則該表稱爲聚集表。如果表沒有聚集索引,則其數據行存儲在一個稱爲堆的無序結構中。

  每個表幾乎都對列定義聚集索引來實現下列功能:

  1、可用於經常使用的查詢。

  2、提供高度唯一性。

  在創建聚集索引之前,應先了解數據是如何被訪問的。考慮對具有以下特點的查詢使用聚集索引:

  使用運算符(如 BETWEEN、>、>=、< 和 <=)返回一系列值。

  使用聚集索引找到包含第一個值的行後,便可以確保包含後續索引值的行物理相鄰。例如,如果某個查詢在一系列採購訂單號間檢索記 錄,PurchaseOrderNumber 列的聚集索引可快速定位包含起始採購訂單號的行,然後檢索表中所有連續的行,直到檢索到最後的採購訂單號。

  返回大型結果集。

  使用 JOIN 子句;一般情況下,使用該子句的是外鍵列。

  使用 ORDER BY 或 GROUP BY 子句。

  在 ORDER BY 或 GROUP BY 子句中指定的列的索引,可以使數據庫引擎 不必對數據進行排序,因爲這些行已經排序。這樣可以提高查詢性能。

  聚集索引不適用於具有下列屬性的列:

  頻繁更改的列

  這將導致整行移動,因爲數據庫引擎 必須按物理順序保留行中的數據值。這一點要特別注意,因爲在大容量事務處理系統中數據通常是可變的。

  寬鍵

  寬鍵是若干列或若干大型列的組合。所有非聚集索引將聚集索引中的鍵值用作查找鍵。爲同一表定義的任何非聚集索引都將增大許多,這是因爲非聚集索引項包含聚集鍵,同時也包含爲此非聚集索引定義的鍵列。 非聚集索引

  非聚集索引具有獨立於數據行的結構。非聚集索引包含非聚集索引鍵值,並且每個鍵值項都有指向包含該鍵值的數據行的指針。

  從非聚集索引中的索引行指向數據行的指針稱爲行定位器。行定位器的結構取決於數據頁是存儲在堆中還是聚集表中。對於堆,行定位器是指向行的指針。對於聚集表,行定位器是聚集索引鍵。

  在 SQL Server 2005 中,可以向非聚集索引的葉級別添加非鍵列以跳過現有的索引鍵限制(900 字節和 16 鍵列),並執行完整範圍內的索引查詢。

  非聚集索引與聚集索引具有相同的 B 樹結構,它們之間的顯著差別在於以下兩點:

  1、基礎表的數據行不按非聚集鍵的順序排序和存儲。

  2、非聚集索引的葉層是由索引頁而不是由數據頁組成。

  設計非聚集索引時需要注意數據庫的特徵:

  更新要求較低但包含大量數據的數據庫或表可以從許多非聚集索引中獲益從而改善查詢性能。

  決策支持系統應用程序和主要包含只讀數據的數據庫可以從許多非聚集索引中獲益。查詢優化器具有更多可供選擇的索引用來確定最快的訪問方法,並且數據庫的低更新特徵意味着索引維護不會降低性能。

  聯機事務處理應用程序和包含大量更新表的數據庫應避免使用過多的索引。此外,索引應該是窄的,即列越少越好。

  一個表如果建有大量索引會影響 INSERT、UPDATE 和 DELETE 語句的性能,因爲所有索引都必須隨表中數據的更改進行相應的調整。

  唯一索引

  唯一索引確保索引鍵不包含重複的值,因此,表或視圖中的每一行在某種程度上是唯一的。

  聚集索引和非聚集索引都可以是唯一索引。

  包含性列索引

  一種非聚集索引,它擴展後不僅包含鍵列,還包含非鍵列。

  索引涵蓋

  指查詢中的SELECT與WHERE子句的所用列同時也屬於非聚集索引的情況。這樣就可以更快檢索數據,因爲所有信息都可以直接來自於索引頁,從而SQL Server可以避免訪問數據頁。加上獨立的索引文件組,可以用最快速度訪問數據。

  請看如下表示例:

  A.創建簡單非聚集索引 以下示例爲 Purchasing.ProductVendor 表的 VendorID 列創建非聚集索引。 

 

      USE AdventureWorks;
  GO
  CREATE INDEX IX_ProductVendor_VendorID
  ON Purchasing.ProductVendor (VendorID);
  GO

  B. 創建簡單非聚集組合索引

  以下示例爲 Sales.SalesPerson 表的 SalesQuota 和 SalesYTD 列創建非聚集組合索引。 

 

      CREATE NONCLUSTERED INDEX IX_SalesPerson_SalesQuota_SalesYTD
  ON Sales.SalesPerson (SalesQuota, SalesYTD);
  GO

  C. 創建唯一非聚集索引

  以下示例爲 Production.UnitMeasure 表的 Name 列創建唯一的非聚集索引。該索引將強制插入 Name 列中的數據具有唯一性。 

 

      USE AdventureWorks;
  GO
  CREATE UNIQUE INDEX AK_UnitMeasure_Name
  ON Production.UnitMeasure(Name);
  GO

  無論何時對基礎數據執行插入、更新或刪除操作,SQL Server 2005 數據庫引擎都會自動維護索引。隨着時間的推移,這些修改可能會導致索引中的信息分散在數據庫中(含有碎片)。當索引包含的頁中的邏輯排序(基於鍵值)與數 據文件中的物理排序不匹配時,就存在碎片。碎片非常多的索引可能會降低查詢性能,導致應用程序響應緩慢。這個時候,我們需要做得就是重新組織和重新生成索 引。重新生成索引將刪除該索引並創建一個新索引。此過程中將刪除碎片,通過使用指定的或現有的填充因子設置壓縮頁來回收磁盤空間,並在連續頁中對索引行重 新排序(根據需要分配新頁)。這樣可以減少獲取所請求數據所需的頁讀取數,從而提高磁盤性能。

  可以使用下列方法重新生成聚集索引和非聚集索引:

  帶 REBUILD 子句的 ALTER INDEX。此語句將替換 DBCC DBREINDEX 語句。

  帶 DROP_EXISTING 子句的 CREATE INDEX。

  示例如下:

  A. 重新生成索引

以下示例將重新生成單個索引。  
      USE AdventureWorks;
  GO
  ALTER INDEX PK_Employee_EmployeeID ON HumanResources.Employee
  REBUILD;
  GO


  B.重新生成表的所有索引並指定選項
  下面的示例指定了 ALL 關鍵字。這將重新生成與表相關聯的所有索引。其中指定了三個選項。 
      ALTER INDEX ALL ON Production.Product
  REBUILD WITH (FILLFACTOR = 80, SORT_IN_TEMPDB = ON,
  STATISTICS_NORECOMPUTE = ON);
  GO

      2 Oracle 中的索引
  索引是Oracle使用的加速表中數據檢索的數據庫對象。
  下面的情況,可以考慮使用索引:
  1) 大表
  2) 主鍵(自動索引)
  3) 單鍵列(自動索引)
  4) 外鍵列(自動索引)
  5) 大表上WHERE子句常用的列
  6) ORDER BY 或者GROUP BY子句中使用的列。
  7) 至少返回表中20%行的查詢
  8) 不包含null值的列。
  Oracle中的索引包含有如下幾種類型:
  B*樹索引:這是Oracle中最常用的索引,它的構造類似於二叉樹,能根據鍵提供一行或一個行集的快速訪問,通常只需要很少的讀操作就能找到正確的行。B*樹索引由兩列組成,第一列是ROWID, 它是行的位置;第二列是正被索引列的值。

  圖:典型的B*樹索引布局

  這個樹底層的塊稱爲葉子節點(leaf node) 或(leaf block),其中分別包含各個索引鍵以及一個rowid(它是指向所索引的行)。葉子節點之上的內部塊稱爲分支塊(branch block),這些節點用於實現導航。例如,如果想在索引中找到值20,要從樹頂開始,找到左分支,我們檢查這個塊,並發現需要找到範圍"20..25" 的塊,這個塊將是葉子塊,其中會指示包含數20的行。索引的葉子節點實際上構成了一個雙向鏈表。一旦發現要從葉子節點中的那裏開始,執行值的有序掃描 (index range scan)就會很容易,我們就不必再在索引結構中導航:而只需根據葉子節點向前或向後掃描就可以了。

  B*樹的特點之一是:所有葉子塊都應該在樹的同一層上,這一層稱之爲索引的高度, 它說明所有從索引的根塊到葉子塊的遍歷都會訪問同樣數目的塊。也就是說,對於形如"SELECT INDEX_column FROM TABLE WHERE INXDEX_column =:X"的索引,要達到葉子塊來獲取第一行,不論使用的:X值是什麼,都會執行同樣數目的I/O,由此可見B*樹的B代表的是balanced,所謂的"Height balanced"。大多數B*樹索引的高度都是2或3,即使索引中有數百萬行記錄也是如此,這說明,一般而言,在索引中找到一個鍵只需要2到3次I/O , 這確實不錯。

  B*樹是一個極佳的通用索引機制,無論是大表還是小表都很適用,隨着底層表大小增長,獲取數據的性能僅會稍有惡化。

  比如,我們爲customers表建立一個常見的B*樹索引: 

 

      CREATE INDEX IDX_Cus_City on customers(city)

  B*樹索引有以下子類型:

  複合索引

  複合索引也是一種B*樹索引,它由多列組成。當我們擁有使用兩列或超過兩列的頻繁查詢時,就使用B*樹複合索引,而其所使用的兩列或多列在 where子句中and邏輯操作符連接。因爲複合索引中列的順序很重要,所以確信以最有效的索引能排列他們,可以參考用作列排序的下面的兩個準則 :

  1) 前導列應該是查詢中使用最頻繁的列。

  2) 前導列應該是選擇最多的列,這意味着它比後面的列具有更高的基數。

  複合索引在下列情況中具有優勢:

  1)假定在WHERE子句中頻繁使用下面的條件:order_status_id = 1 和order_date = ‘dd-mon-yyyy’。如果爲每一列創建一個索引,那麼爲了搜索列的值,兩個索引都要被讀取,但是如果爲兩列都創建一個複合索引,那麼只有一個索引 被讀取,這樣無疑比兩個索引要求更少的I/O

  2) 使用前面例子中同樣的條件,如果創建一個複合索引,將更快地檢索行,因爲你正在排除了所有order_status_id 不是1的行,從而減少了搜索order_date的行數。

  反向鍵索引

  B*樹索引的另一個特點是能夠將索引鍵“反轉”。首先,你可以問問自己“爲什麼想這麼做?” B*樹索引是爲特定的環境、特定的問題而設計的。實現B*樹索引的目的是爲了減少“右側”索引中對索引葉子塊的競爭,比如在一個Oracle RAC 環境中,某些列用一個序列值或時間戳填充,這些列上建立的索引就屬於“右側”(right-hand-side)索引。

  RAC 是一種Oracle 配置,其中多個實例可以裝載和打開同一個數據庫。如果兩個實例需要同時修改同一個數據塊,它們會通過一個硬件互連(interconnect)來回傳遞這 個塊來實現共享,互連是兩個(或多個)機器之間的一條專用網絡連接。如果某個利用一個序列填充,這個列上有一個主鍵索引 ,那麼每個人插入新值時,都會視圖修改目前索引結構右側的左塊(見本文圖一,其中顯示出索引中較高的值都放在右側,而較低的值放在左側)。如果對用序列填 充的列上的索引進行修改,就會聚集在很少的一組葉子塊上。倘若將索引的鍵反轉,對索引進行插入時,就能在索引中的所有葉子鍵上分佈開(不過這往往會使索引 不能得到充分地填充)。

  反向鍵索引創建語句語法如下: 

 

      CREATE INDEX index_name on table_name(column_name) REVERSE ;

  降序索引

  降序索引(descending index)是oracle 8i引入的,用以擴展B*樹索引的功能,它允許在索引中以降序(從大到小的順序)存儲一列。在oracle8i及以上版本中,DESC關鍵字確實會改變創建和使用索引的的方式。

  我們可以這樣創建降序索引

 

      CREATE INDEX IDX_jobs_title on hr.jobs (job_title DESC);
  SET autotrace traceonly EXPLAIN;
  SELECT * FROM hr.jobs
  WHERE job_title Between 'a' AND 'ZZZZZZZZZZZ ';  Execution Plan
  ----------------------------------------------------------
  0 SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=1 Bytes=33)
  1 0 FILTER
  2 1 TABLE ACCESS (BY INDEX ROWID) OF 'JOBS' (Cost=1 Card=1 B
  ytes=33)
  3 2 INDEX (RANGE SCAN) OF 'IDX_JOBS_TITLE' (NON-UNIQUE) (C
  ost=2 Card=1)               
  SQL> SELECT * from hr.jobs
  2 WHERE job_title between 'a' and 'ZZZZZZZZZZZ ';
  Execution Plan
  ----------------------------------------------------------
  0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=33)
  1 0 FILTER
  2 1 TABLE ACCESS (FULL) OF 'JOBS' (Cost=2 Card=1 Bytes=33)
  SQL> DROP INDEX IDX_jobs_title ;
  SQL> CREATE INDEX IDX_jobs_title on hr.jobs (job_title );
  SQL> Select * FROM hr.jobs
  2 Where job_title between 'a' and 'ZZZZZZZZZZZ ';
  Execution Plan
  ----------------------------------------------------------
  0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=33)
  1 0 FILTER
  2 1 TABLE ACCESS (FULL) OF 'JOBS' (Cost=2 Card=1 Bytes=33)

  位圖索引

  位圖索引(bitmap index)是從Oracle7.3 版本開始引入的。目前Oracle企業版和個人版都支持位圖索引,但標準版不支持。位圖索引是爲數據倉庫/在線分析查詢環境設計的,在此所有查詢要求的數據在系統實現時根本不知道。位圖索引特別不適用於OLTP 系統,如果系統中的數據會由多個併發會話頻繁地更新,這種系統也不適用位圖索引。

  位圖索引是這樣一種結構,其中用一個索引鍵條目存儲指向多行的指針;這與B*樹結構不同,在B*樹結構中,索引鍵和表中的行存在着對應關係。在位圖索引中,可能只有很少的索引條目,每個索引條目指向多行。而在傳統的B*樹中,一個索引條目就指向一行。

  B*樹索引一般來講應當是選擇性的。與之相反,位圖索引不應是選擇性的,一般來講它們應該“沒有選擇性“。如果有大量在線分析查詢,特別是查詢 以一種即席方式引用了多列或者會生成諸如COUNT 之類的聚合,在這樣的環境中,位圖索引就特別有用 。位圖索引使用 CREATE BITMAP INDEX index_name ON table_name(column_name1,column_name2) TABLESPACE tablespace_name命令語法創建。

 

 

 

 

SQL Server查詢優化技術及索引

From: http://www.cnblogs.com/lovewindy/archive/2005/02/19/105959.html

 

在《數據庫原理》裏面,對聚簇索引的解釋是:聚簇索引的順序就是數據的物理存儲順序,而對非聚簇索引的解釋是:索引順序與數據物理排列順序無關。正式因爲如此,所以一個表最多只能有一個聚簇索引。

不過這個定義太抽象了。在SQL Server中,索引是通過二叉樹的數據結構來描述的,我們可以這麼理解聚簇索引:索引的葉節點就是數據節點。而非聚簇索引的葉節點仍然是索引節點,只不過有一個指針指向對應的數據塊。如下圖:


非聚簇索引

 


聚簇索引


聚簇索引與非聚簇索引的本質區別到底是什麼?什麼時候用聚簇索引,什麼時候用非聚簇索引?

這是一個很複雜的問題,很難用三言兩語說清楚。我在這裏從SQL Server索引優化查詢的角度簡單談談(如果對這方面感興趣的話,可以讀一讀微軟出版的《Microsoft SQL Server 2000數據庫編程》第3單元的數據結構引論以及第6、13、14單元)。


一、索引塊與數據塊的區別

大家都知道,索引可以提高檢索效率,因爲它的二叉樹結構以及佔用空間小,所以訪問速度塊。讓我們來算一道數學題:如果表中的一條記錄在磁盤上佔用1000字節的話,我們對其中10字節的一個字段建立索引,那麼該記錄對應的索引塊的大小隻有10字節。我們知道,SQL Server的最小空間分配單元是“頁(Page)”,一個頁在磁盤上佔用8K空間,那麼這一個頁可以存儲上述記錄8條,但可以存儲索引800條。現在我們要從一個有8000條記錄的表中檢索符合某個條件的記錄,如果沒有索引的話,我們可能需要遍歷8000條×1000字節/8K字節=1000個頁面才能夠找到結果。如果在檢索字段上有上述索引的話,那麼我們可以在8000條×10字節/8K字節=10個頁面中就檢索到滿足條件的索引塊,然後根據索引塊上的指針逐一找到結果數據塊,這樣IO訪問量要少的多。


二、索引優化技術

是不是有索引就一定檢索的快呢?答案是否。有些時候用索引還不如不用索引快。比如說我們要檢索上述表中的所有記錄,如果不用索引,需要訪問8000條×1000字節/8K字節=1000個頁面,如果使用索引的話,首先檢索索引,訪問8000條×10字節/8K字節=10個頁面得到索引檢索結果,再根據索引檢索結果去對應數據頁面,由於是檢索所有數據,所以需要再訪問8000條×1000字節/8K字節=1000個頁面將全部數據讀取出來,一共訪問了1010個頁面,這顯然不如不用索引快。

SQL Server內部有一套完整的數據檢索優化技術,在上述情況下,SQL Server的查詢計劃(Search Plan)會自動使用表掃描的方式檢索數據而不會使用任何索引。那麼SQL Server是怎麼知道什麼時候用索引,什麼時候不用索引的呢?SQL Server除了日常維護數據信息外,還維護着數據統計信息,下圖是數據庫屬性頁面的一個截圖:

從圖中我們可以看到,SQL Server自動維護統計信息,這些統計信息包括數據密度信息以及數據分佈信息,這些信息幫助SQL Server決定如何制定查詢計劃以及查詢是是否使用索引以及使用什麼樣的索引(這裏就不再解釋它們到底如何幫助SQL Server建立查詢計劃的了)。我們還是來做個實驗。建立一張表:tabTest(ID, unqValue,intValue),其中ID是整形自動編號主索引,unqValue是uniqueidentifier類型,在上面建立普通索引,intValue 是整形,不建立索引。之所以掛上一個沒有索引的intValue字段,就是防止SQL Server使用索引覆蓋查詢優化技術,這樣實驗就起不到作用了。向表中錄入10000條隨機記錄,代碼如下:

 

CREATE TABLE [dbo].[tabTest] (
 
[ID] [int] IDENTITY (11NOT NULL ,
 
[unqValue] [uniqueidentifier] NOT NULL ,
 
[intValue] [int] NOT NULL 
ON [PRIMARY]
GO

ALTER TABLE [dbo].[tabTest] WITH NOCHECK ADD 
 
CONSTRAINT [PK_tabTest] PRIMARY KEY  CLUSTERED 
 (
  
[ID]
 )  
ON [PRIMARY] 
GO

ALTER TABLE [dbo].[tabTest] ADD 
 
CONSTRAINT [DF_tabTest_unqValue] DEFAULT (newid()) FOR [unqValue]
GO

CREATE  INDEX [IX_tabTest_unqValue] ON [dbo].[tabTest]([unqValue]ON [PRIMARY]
GO

declare @i int
declare @v int

set @i=0
while @i<10000
begin
    
set @v=rand()*1000    
    
insert into tabTest ([intValue]values (@v)
    
set @i=@i+1
end

 

然後我們執行兩個查詢並查看執行計劃,如圖:(在查詢分析器的查詢菜單中可以打開查詢計劃,同時圖上第一個查詢的GUID是我從數據庫中找的,大家做實驗的時候可以根據自己數據庫中的值來定):



從圖中可以看出,在第一個查詢中,SQL Server使用了IX_tabTest_unqValue索引,根據箭頭方向,計算機先在索引範圍內找,找到後,使用Bookmark Lookup將索引節點映射到數據節點上,最後給出SELECT結果。在第二個查詢中,系統直接遍歷表給出結果,不過它使用了聚簇索引,爲什麼呢?不要忘了,聚簇索引的頁節點就是數據節點!這樣使用聚簇索引會更快一些(不受數據刪除、更新留下的存儲空洞的影響,直接遍歷數據是要跳過這些空洞的)。

下面,我們在SQL Server中將ID字段的聚簇索引更改爲非聚簇索引,然後再執行select * from tabTest,這回我們看到的執行計劃變成了:

SQL Server沒有使用任何索引,而是直接執行了Table Scan,因爲只有這樣,檢索效率纔是最高的。


三、聚簇索引與非聚簇索引的本質區別

現在可以討論聚簇索引與非聚簇索引的本質區別了。正如本文最前面的兩個圖所示,聚簇索引的葉節點就是數據節點,而非聚簇索引的頁節點仍然是索引檢點,並保留一個鏈接指向對應數據塊。

還是通過一道數學題來看看它們的區別吧:假設有一8000條記錄的表,表中每條記錄在磁盤上佔用1000字節,如果在一個10字節長的字段上建立非聚簇索引主鍵,需要二叉樹節點16000個(這16000個節點中有8000個葉節點,每個頁節點都指向一個數據記錄),這樣數據將佔用8000條×1000字節/8K字節=1000個頁面;索引將佔用16000個節點×10字節/8K字節=20個頁面,共計1020個頁面。

同樣一張表,如果我們在對應字段上建立聚簇索引主鍵,由於聚簇索引的頁節點就是數據節點,所以索引節點僅有8000個,佔用10個頁面,數據仍然佔有1000個頁面。

下面我們看看在執行插入操作時,非聚簇索引的主鍵爲什麼比聚簇索引主鍵要快。主鍵約束要求主鍵不能出現重複,那麼SQL Server是怎麼知道不出現重複的呢?唯一的方法就是檢索。對於非聚簇索引,只需要檢索20個頁面中的16000個節點就知道是否有重複,因爲所有主鍵鍵值在這16000個索引節點中都包含了。但對於聚簇索引,索引節點僅僅包含了8000箇中間節點,至於會不會出現重複必須檢索另外1000個頁數據節點才知道,那麼相當於檢索10+1000=1010個頁面才知道是否有重複。所以聚簇索引主鍵的插入速度要比非聚簇索引主鍵的插入速度慢很多。

讓我們再來看看數據檢索的效率,如果對上述兩表進行檢索,在使用索引的情況下(有些時候SQL Server執行計劃會選擇不使用索引,不過我們這裏姑且假設一定使用索引),對於聚簇索引檢索,我們可能會訪問10個索引頁面外加1000個數據頁面得到結果(實際情況要比這個好),而對於非聚簇索引,系統會從20個頁面中找到符合條件的節點,再映射到1000個數據頁面上(這也是最糟糕的情況),比較一下,一個訪問了1010個頁面而另一個訪問了1020個頁面,可見檢索效率差異並不是很大。所以不管非聚簇索引也好還是聚簇索引也好,都適合排序,聚簇索引僅僅比非聚簇索引快一點。


結語

好了,寫了半天,手都累了。關於聚簇索引與非聚簇索引效率問題的實驗就不做了,感興趣的話可以自己使用查詢分析器對查詢計劃進行分析。SQL Server是一個很複雜的系統,尤其是索引以及查詢優化技術,Oracle就更復雜了。瞭解索引以及查詢背後的事情不是什麼壞事,它可以幫助我們更爲深刻的瞭解我們的系統。

 

 

SQL Server基礎知識之:設計和實現視圖

設計和實現視圖可謂是數據庫物理設計中的一個非常重要的步驟。從一般意義上說,設計和實現視圖應該遵循下面的一些建議和原則。

以下內容摘在文檔,我對某些重點進行了補充說明(紅色部分)

只能在當前數據庫中創建視圖。 但是,如果使用分佈式查詢定義視圖,則新視圖所引用的表和視圖可以存在於其他數據庫甚至其他服務器中。
  • 分佈式視圖是可行的,但隨着SQL Server本身能力的提高,例如SQL Server 2005開始支持表分區等技術之後,分佈式視圖應該儘量少用。
  • 所謂分佈式視圖的一個最大的問題就是將表物理上分開在多個數據庫甚至服務器中,這增加了維護和查詢的難度
視圖名稱必須遵循標識符的規則,且對每個架構都必須唯一。 此外,該名稱不得與該架構包含的任何表的名稱相同。
  • 一個可以借鑑的做法是:在視圖名稱之前添加一個前綴 vw
您可以對其他視圖創建視圖。Microsoft SQL Server 允許嵌套視圖。但嵌套不得超過 32 層。 根據視圖的複雜性及可用內存,視圖嵌套的實際限制可能低於該值。
  • 一般不建議超過2層
不能將規則或 DEFAULT 定義與視圖相關聯。 不能將 AFTER 觸發器與視圖相關聯,只有 INSTEAD OF 觸發器可以與之相關聯。
  • 除非萬不得已,一般不建議使用觸發器
定義視圖的查詢不能包含 COMPUTE 子句、COMPUTE BY 子句或 INTO 關鍵字。
  • 很多朋友不知道:COMPUTER和COMPUTER BY語句僅僅用於一些特殊場合,用於生成總計行。大致有如下的效果

image

該特性不能用於視圖,但可以直接用於查詢

 

定義視圖的查詢不能包含 ORDER BY 子句,除非在 SELECT 語句的選擇列表中還有一個 TOP 子句。
  • 這個很有意思,如果要訪問所有的呢,還必須是寫TOP 100 PERCENT
定義視圖的查詢不能包含指定查詢提示的 OPTION 子句。 定義視圖的查詢不能包含 TABLESAMPLE 子句。
  • 關於TABLESAMPLE語句,大家可能也比較陌生,這是一個用於對數據進行抽樣的。它和TOP語句不同,TOP語句是有固定大小的,而TABLESAMPLE返回的數據,可能多,可能少,甚至可能沒有
  • 我之前有一篇文章講述這個語法 http://www.cnblogs.com/chenxizhang/archive/2009/05/19/1460040.html
不能爲視圖定義全文索引定義。 不能創建臨時視圖,也不能對臨時表創建視圖。
  • 在SQL Server 2005中,可以通過CTE(Common Table Expression)來實現該功能
  • 之前的版本,大致的做法是使用臨時表,表變量,函數等等
不能刪除參與到使用 SCHEMABINDING 子句創建的視圖中的視圖、表或函數,除非該視圖已被刪除或更改而不再具有架構綁定。 另外,如果對參與具有架構綁定的視圖的表執行 ALTER TABLE 語句,而這些語句又會影響該視圖的定義,則這些語句將會失敗。
  • 如果未使用 SCHEMABINDING 子句創建視圖,則對視圖下影響視圖定義的對象進行更改時,應運行 sp_refreshview。 否則,當查詢視圖時,可能會生成意外結果
  • 強烈建議對某些非常重要的視圖,添加SCHEMABINDING 子句。

image

儘管查詢引用一個已配置全文索引的表時,視圖定義可以包含全文查詢,仍然不能對視圖執行全文查詢。 下列情況下必須指定視圖中每列的名稱:
  • 視圖中的任何列都是從算術表達式、內置函數或常量派生而來。
  • 視圖中有兩列或多列原應具有相同名稱(通常由於視圖定義包含聯接,因此來自兩個或多個不同表的列具有相同的名稱)。
  • 希望爲視圖中的列指定一個與其源列不同的名稱。 (也可以在視圖中重命名列。) 無論重命名與否,視圖列都會繼承其源列的數據類型。

    若要創建視圖,您必須獲取由數據庫所有者授予的此操作執行權限,如果使用 SCHEMABINDING 子句創建視圖,則必須對視圖定義中引用的任何表或視圖具有相應的權限。

    默認情況下,由於行通過視圖進行添加或更新,當其不再符合定義視圖的查詢的條件時,它們即從視圖範圍中消失。 例如,創建一個定義視圖的查詢,該視圖從表中檢索員工的薪水低於 $30,000 的所有行。如果員工的薪水漲到 $32,000,因其薪水不符合視圖所設條件,查詢時視圖不再顯示該特定員工。 但是,WITH CHECK OPTION 子句強制所有數據修改語句均根據視圖執行,以符合定義視圖的 SELECT 語句中所設條件。 如果使用該子句,則對行的修改不能導致行從視圖中消失。 任何可能導致行消失的修改都會被取消,並顯示錯誤。

 

發佈了148 篇原創文章 · 獲贊 8 · 訪問量 21萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章