1. 程式人生 > >資料庫索引的建立 和 注意事項

資料庫索引的建立 和 注意事項

PS:索引不是給你使用的,而是資料庫本身使用,索引只是為了讓你的查詢更加快速而已

CREATE INDEX index_name
ON table_name (column_name)

註釋:”column_name” 規定需要索引的列。
SQL CREATE UNIQUE INDEX 語法
在表上建立一個唯一的索引。唯一的索引意味著兩個行不能擁有相同的索引值。

CREATE UNIQUE INDEX index_name
ON table_name (column_name)

CREATE INDEX 例項
本例會建立一個簡單的索引,名為 “PersonIndex”,在 Person 表的 LastName 列:

CREATE INDEX PersonIndex
ON Person (LastName) 

如果您希望以降序索引某個列中的值,您可以在列名稱之後新增保留字 DESC:

CREATE INDEX PersonIndex
ON Person (LastName DESC) 

假如您希望索引不止一個列,您可以在括號中列出這些列的名稱,用逗號隔開:

CREATE INDEX PersonIndex
ON Person (LastName, FirstName)

1、索引不要與表存放在同一個表空間內;
2、一個表的索引不要過多;

3、對於大表而且使用頻繁的表,在生產時最好不要去加索引;
如果對大表進行索引,取出的資料大於總量的5%至10%,使用索引掃描會效率下降很多。如果通過索引,取出資料量為總量的50%以上,這個時候還不如全表掃描來得快。
4、資料量小的表,使用不頻繁的不要單獨另建立索引;

5、在查詢條件中幾個條件一起使用的,適合建立組合索引,否則不要建立組合索引,當單獨引用非第一欄位時將發生全表掃描;
在Oracle9i之前,只有在使用到索引的前導索引時才可以使用組合索引

6,在查詢的時候,where條件不要對索引的列做處理,而要對後面的條件欄位做處理。否則用不上這個列上的索引。
如: score_date 是varchar2型別,該列上有索引。
select
……
where trim(replace(s.SCORE_DATE, ‘-‘, ”)) <= ‘20071201’
……
上面這條sql用不上score_date列上的索引。
下面這條sql就能用上索引。
select
……
where SCORE_DATE <= ‘20071201’
……
如果不是基於函式的索引,那麼在SQL語句的WHERE子句中對存在索引的列使用函式時,會使優化器忽略掉這些索引。
下面的查詢不會使用索引(只要它不是基於函式的索引)
select empno,ename,deptno
from emp
where trunc(hiredate)=’01-MAY-81’;
把上面的語句改成下面的語句,這樣就可以通過索引進行查詢。
select empno,ename,deptno
from emp
where hiredate<(to_date(‘01-MAY-81’)+0.9999);

6.1: 表的某個欄位是字元型的, 那麼傳入數字值不加引號的話,sql不走索引:
例子:
docset表的todocid欄位新建了索引,但是這個sql就是不走索引,加hint也沒有用.

select /+INDEX(docset IX_DOCSET_TODOCID)/ *
from docset
WHERE REPLYSENDFLAG = 1
and TODOCID in (141429, 141441);
執行計劃如下:
SELECT STATEMENT, GOAL = ALL_ROWS Cost=1592 Cardinality=2 Bytes=650
TABLE ACCESS FULL Object wner=SEALDATA Object name=DOCSET Cost=1592 Cardinality=2 Bytes=650
後來發現, todocid這個欄位是VARCHAR2(20)型別的, 不是number, 所以傳入的值是數字的時候,要加引號,才能走索引, 否則要使用函式索引才能有效.

select /+INDEX(docset IX_DOCSET_TODOCID)/ *
from docset
WHERE REPLYSENDFLAG = 1
and TODOCID in (‘141429’, ‘141441’);
執行計劃如下:
SELECT STATEMENT, GOAL = ALL_ROWS Cost=1 Cardinality=2 Bytes=650
INLIST ITERATOR
TABLE ACCESS BY INDEX ROWID Object wner=SEALDATA Object name=DOCSET Cost=1 Cardinality=2 Bytes=650
INDEX RANGE SCAN Object wner=SEALDATA Object name=IX_DOCSET_TODOCID Cost=1 Cardinality=2

7.一些SQL的寫法會限制索引的使用:1.where子句中如果使用in、or、like、!= <>,均會導致索引不能正常使用,將”<>”換成”>and<”;將”is not null “換成”>=chr(0)”;2.使用函式時,該列就不能使用索引。3.比較不匹配資料型別時,該索引將會被忽略
一些SQL語句優化的寫法:1.如果from是雙表的查詢時,大表放在前面,小表放在後面(基礎表)。最後面的表是基礎表。(只在基於規則的優化器中有效)2.如果三表查詢時,選擇交叉表(intersection table)作為基礎表.(只在基於規則的優化器中有效)3.寫where條件時,有索引欄位的判斷在前,其它欄位的判斷在後;如果where條件中用到複合索引,按照索引列在複合索引中出現的順序來依次寫where條件;4.查詢數量較大時,使用表連線代替IN,EXISTS,NOT IN,NOT EXISTS等。5.ORACLE採用自下而上的順序解析WHERE子句,那些可以過濾掉最大數量記錄的條件必須寫在WHERE子句的末尾

8,關於點陣圖索引。
怎樣使用點陣圖索引?注意點是什麼?語句怎樣寫呢: dba_indexes index_type
OLTP不能使用點陣圖索引,這應該是謹記的!
create bitmap index t_index1 on TEST_ZHP (c1);
當列上的值型別比較少時,適合使用點陣圖索引

olap:online analysis processing 聯機分析處理, 適用於dss(decision support system決策支援系統,也就是人們常說的資料倉庫系統)
主要面向分析,一般基於資料倉庫,資料主要為只讀方式,涉及海量查詢,select,主要處理歷史資料,出報表等。
olap是聯機分析處理,它所擅長的是對企業的當前和歷史資料進行分析,對企業的狀況進行分析,主要是針對企業管理人員

點陣圖索引是oracle的比較引人注目的地方,其主要用在olap(聯機資料分析)方面,也就是資料倉庫。
點陣圖索引在實際密集型OLTP(資料事務處理)中用得比較少,因為OLTP會對錶進行大量的刪除、修改 ,建議使用B-tree索引

oltp :online transaction processing 聯機事務處理 適用於mis ,網站等小事務的交易系統!
主要面向事務處理,一般為單行或幾行操作。update , 寫密集型
它所擅長的就是處理當前實時的資料,最新的業務資料,實現企業業務的計算機化,主要針對企業的業務人員