索引

該文章來源於網頁整理.

 

1.查看目前已經建立的索引

在同一張表上可以有多個索引,通過查詢數據字典視圖dba_indexs和user_indexs,可以顯示索引信息。其中dba_indexs用於顯示數據庫所有的索引信息,而user_indexs用於顯示當前用戶的索引信息
select index_name from all_indexes where table_name = ‘PICTURE’; 表名必須大寫

create index picture_album_idx on picture (aid);  

按照數據存儲方式,可以分爲B*樹、反向索引、位圖索引; 
按照索引列的個數分類,可以分爲單列索引、複合索引; 
按照索引列值的唯一性,可以分爲唯一索引和非唯一索引。 
此外還有函數索引,全局索引,分區索引... 

對於索引我還要說: 
在不同的情況,我們會在不同的列上建立索引,甚至建立不同種類的索引。B*樹索引建立在重複值很少的列上,而位圖索引則建立在重複值很多、不同值相對固定的列上。


2.
可以說,一張沒有索引的數據表,就像一個只有書櫃而沒有索引卡片櫃的圖書館,書庫裏面塞滿了一堆亂七八糟的圖書。當讀者對管理員提交查詢請求後,管理員就一頭鑽進書庫,對照查找內容從頭開始一架一櫃的逐本查找。運氣好的話,在第一個書架的第一本書就  找到了,運氣不好的話,要到最後一個書架的最後一本書才找到。可以說,一張沒有索引的數據表,就像一個只有書櫃而沒有索引卡片櫃的圖書館,書庫裏面塞滿了一堆亂七八糟的圖書。當讀者對管理員提交查詢請求後,管理員就一頭鑽進書庫,對照查找內容從頭開始一架一櫃的逐本查找。運氣好的話,在第一個書架的第一本書就  找到了,運氣不好的話,要到最後一個書架的最後一本書才找到。


 如果我們在建立非聚集索引之前先建立了聚集索引的話,那麼非聚集索引就可以使用聚集索引的關鍵字進行檢索。
在只建立了非聚集索引的情況下,每個葉級節點指明瞭記錄的行定位符(RID);而在既有聚集索引又有非聚集索引的情況下,每個葉級節點所指向的是該聚集索引的索引鍵值,即數據記錄本身。 


  這就完全和我們在“索引的基本概念”中講到的現實場景完全一樣了,當數據發生更新的時候,SQLS只負責對聚集索引的鍵值加以維護,而不必考慮非聚集索引。只要我們在ID類的字段上建立聚集索引,而在其它經常需要查詢的字段上建立非聚集索引,通過這種科學的、有針對性的在一張表上分別建立聚集索引和非聚集索引的方法,我們既享受了索引帶來的靈活與快捷,又相對避免了維護索引所導致的大量的額外資源消耗。 


在創建索引時,可以爲這個索引指定一個填充因子,以便在索引的每個葉級頁面上保留一定百分比的空間,將來數據可以進行擴充和減少頁分裂。

只有在表中根據現有數據創建新索引,並且可以預見將來會對這些數據進行哪些更改時,設置填充因子纔有意義。

 

右擊Northwind數據庫→單擊“屬性”→選擇“Options”選項卡,觀察“Settings”下的各項複選項:
從Settings中我們可以看到,在數據庫中,SQLS將默認的自動創建和更新統計信息,這些統計信息包括數據密度和分佈信息,正是它們幫助SQLS確定最佳的查詢策略:建立查詢計劃和是否使用索引以及使用什麼樣的索引。

索引的兩個重要屬性----惟一性索引和複合性索引:
如果表中已經有一個主鍵約束或者惟一性約束,那麼當創建表或者修改表時,SQLS自動創建一個惟一性索引.


索引可以分爲簇索引和非簇索引,簇索引通過重排表中的數據來提高數據的訪問速度,而非簇索引則通過維護表中的數據指針來提高數據的索引。


3.

索引是數據庫中重要的數據結構,它的根本目的就是爲了提高查詢效率。現在大多數的數據庫產品都採用IBM最先提出的ISAM索引結構。

 

●在經常進行連接,但是沒有指定爲外鍵的列上建立索引,而不經常連接的字段則由優化器自動生成索引。 
●在頻繁進行排序或分組(即進行group by或order by操作)的列上建立索引。 
●在條件表達式中經常用到的不同值較多的列上建立檢索,在不同值少的列上不要建立索引。比如在僱員表的“性別”列上只有“男”與“女”兩個不同值,因此就無必要建立索引。如果建立索引不但不會提高查詢效率,反而會嚴重降低更新速度。 
●如果待排序的列有多個,可以在這些列上建立複合索引(compound index)。 
●使用系統工具。如Informix數據庫有一個tbcheck工具,可以在可疑的索引上進行檢查。在一些數據庫服務器上,索引可能失效或者因爲頻繁操作而使得讀取效率降低,如果一個使用索引的查詢不明不白地慢下來,可以試着用tbcheck工具檢查索引的完整性,必要時進行修復。另外,當數據庫表更新大量數據後,刪除並重建索引可以提高查詢速度。

EG.

(1)在下面兩條select語句中:
   select * from table1  where  field1<=10000 and field1>=0;
   select * from table1  where  field1>=0 and field1<=10000;
   如果數據表中的數據field1都>=0,則第一條select語句要比第二條select語句效率高的多,因爲第二條select語句的第一個條件耗費了大量的系統資源。
   第一個原則:在where子句中應把最具限制性的條件放在最前面。

(2)在下面的select語句中:
   select * from tab  where  a=… and b=… and c=…;
  若有索引index(a,b,c),則where子句中字段的順序應和索引中字段順序一致。
   第二個原則:where子句中字段的順序應和索引中字段順序一致。

以下假設在field1上有唯一索引I1,在field2上有非唯一索引I2。
(3) select field3,field4 from tb where field1='sdf'        快
    select * from tb where field1='sdf'      慢,
因爲後者在索引掃描後要多一步ROWID表訪問。

(4) select field3,field4 from tb where field1>='sdf'        快
select field3,field4 from tb where field1>'sdf'        慢
因爲前者可以迅速定位索引。

(5) select field3,field4 from tb where field2 like 'R%'    快
    select field3,field4 from tb where field2 like '%R'    慢,
    因爲後者不使用索引。

(6) 使用函數如:
select field3,field4 from tb where upper(field2)='RMN'不使用索引。
如果一個表有兩萬條記錄,建議不使用函數;如果一個表有五萬條以上記錄,嚴格禁止使用函數!兩萬條記錄以下沒有限制。

(7) 空值不在索引中存儲,所以
    select field3,field4 from tb where field2 is[not] null不使用索引。

(8) 不等式如
    select field3,field4 from tb where field2!='TOM'不使用索引。
    相似地,
    select field3,field4 from tb where field2 not in('M','P')不使用索引。


(9) 對於多列索引,order by的順序必須和索引的字段順序一致。


4.
建立索引後,並不是每個查詢都會使用索引,只要我們在查詢語句中沒有強制指定索引,索引的選擇和使用方法是SQLSERVER的優化器自動作的選擇,而它選擇的根據是查詢語句的條件以及相關表的統計信息,這就要求我們在寫SQL語句的時候儘量使得優化器可以使用索引。爲了使得優化器能高效使用索引,寫語句的時候應該注意:

A、不要對索引字段進行運算,而要想辦法做變換
SELECT ID FROM T WHERE NUM/2=NUM1    如果NUM有索引應改爲:    SELECT ID FROM T WHERE NUM=NUM1*2

B、 不要對索引字段進行格式轉換
C、 不要對索引字段使用函數
D、不要對索引字段進行多字段連接


多表連接的連接條件對索引的選擇有着重要的意義,所以我們在寫連接條件條件的時候需要特別注意。

  A、多表連接的時候,連接條件必須寫全,寧可重複,不要缺漏。

  B、連接條件儘量使用聚集索引

  C、注意ON、WHERE和HAVING部分條件的區別

考慮聯接優先順序:(1)INNER JOIN(2)LEFT JOIN (注:RIGHT JOIN 用 LEFT JOIN 替代)(3)CROSS JOIN

在IN後面值的列表中,將出現最頻繁的值放在最前面,出現得最少的放在最後面,減少判斷的次數

 

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