日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Oracle索引详解

發(fā)布時間:2023/12/31 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Oracle索引详解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Oracle索引

  • 一、索引介紹
    • 1、什么是索引?
    • 2、使用索引的目的
  • 二、索引的分類及結(jié)構(gòu)
    • 1、邏輯上:
    • 2、物理上:
  • 三、各種索引詳解
    • 1、 B樹索引
      • (1)特點(diǎn):
      • (2)技巧:
    • 2、位圖索引
      • (1)特點(diǎn):
      • (2)技巧:
    • 3、 反向索引
      • (1)特點(diǎn):
      • (2)技巧:
    • 4、HASH索引
      • (1)特點(diǎn):
    • 5、函數(shù)索引
    • 6、分區(qū)索引和全局索引
    • 7、域索引 Domain
  • 四、怎樣建立索引
    • 1、普通索引
    • 2、唯一索引
    • 3、位圖索引
    • 4、組合索引
    • 5、基于函數(shù)索引
    • 6、反向鍵索引
    • 7.重置索引
    • 8.刪除索引
  • 五、索引失效細(xì)節(jié)
    • 1.使用不等于操作符(<>, !=)
    • 2.使用 is null 或 is not null
    • 3.使用函數(shù)
    • 4.比較不匹配的數(shù)據(jù)類型
    • 5.使用like子句
    • 6.使用in
    • 7.如果能不用到排序,則盡量避免排序

一、索引介紹

1、什么是索引?

??索引是建立在表的一列或多個列上的輔助對象,目的是加快訪問表中的數(shù)據(jù);Oracle存儲索引的數(shù)據(jù)結(jié)構(gòu)是B樹,位圖索引也是如此,只不過是葉子節(jié)點(diǎn)不同B數(shù)索引;索引由根節(jié)點(diǎn)、分支節(jié)點(diǎn)和葉子節(jié)點(diǎn)組成,上級索引塊包含下級索引塊的索引數(shù)據(jù),葉節(jié)點(diǎn)包含索引數(shù)據(jù)和確定行實(shí)際位置的rowid。

2、使用索引的目的

??當(dāng)查詢返回的記錄數(shù)排序表<40%非排序表 <7%且表的碎片較多(頻繁增加、刪除)時可以加快查詢速度減少I/O操作消除磁盤排序

二、索引的分類及結(jié)構(gòu)

1、邏輯上:

Single column/Concatenated 單行索引/多行索引
Unique/NonUnique 唯一索引/非唯一索引

2、物理上:

B-tree B樹索引
Bitmap 位圖索引
REVERSE 反向索引
HASHHASH索引
Function-based基于函數(shù)的索引
Partitioned/NonPartitioned 分區(qū)索引/非分區(qū)索引
Domain 域索引

三、各種索引詳解

1、 B樹索引

??Oracle數(shù)據(jù)庫中最常見的索引類型是b-tree索引,也就是B-樹索引,以其同名的計(jì)算科學(xué)結(jié)構(gòu)命名。CREATE INDEX語句時,默認(rèn)就是在創(chuàng)建b-tree索引。沒有特別規(guī)定可用于任何情況。

(1)特點(diǎn):

??適合與大量的增、刪、改(OLTP)
??不能用包含OR操作符的查詢;
??適合高基數(shù)的列(唯一值多)
??典型的樹狀結(jié)構(gòu);
??每個結(jié)點(diǎn)都是數(shù)據(jù)塊;
??大多都是物理上一層、兩層或三層不定,邏輯上三層;
??葉子塊數(shù)據(jù)是排序的,從左向右遞增;
??在分支塊和根塊中放的是索引的范圍;

(2)技巧:

??索引列的值都存儲在索引中。因此,可以建立一個組合(復(fù)合)索引,這些索引可以直接滿足查詢,而不用訪問表。這就不用從表中檢索數(shù)據(jù),從而減少了I/O量。

2、位圖索引

??位圖索引非常適合于決策支持系統(tǒng)(Decision Support System,DSS)和數(shù)據(jù)倉庫,它們不應(yīng)該用于通過事務(wù)處理應(yīng)用程序訪問的表。它們可以使用較少到中等基數(shù)(不同值的數(shù)量)的列訪問非常大的表。盡管位圖索引最多可達(dá)30個列,但通常它們都只用于少量的列。
例如,您的表可能包含一個稱為Sex的列,它有兩個可能值:男和女。這個基數(shù)只為2,如果用戶頻繁地根據(jù)Sex列的值查詢該表,這就是位圖索引的基列。當(dāng)一個表內(nèi)包含了多個位圖索引時,您可以體會到位圖索引的真正威力。如果有多個可用的位圖索引,Oracle就可以合并從每個位圖索引得到的結(jié)果集,快速刪除不必要的數(shù)據(jù)。

(1)特點(diǎn):

??適合與決策支持系統(tǒng);
??做UPDATE代價非常高;
??非常適合OR操作符的查詢;
??基數(shù)比較少的時候才能建位圖索引;

(2)技巧:

??對于有較低基數(shù)的列需要使用位圖索引。性別列就是這樣一個例子,它有兩個可能值:男或女(基數(shù)僅為2)。位圖對于低基數(shù)(少量的不同值)列來說非常快,這是因?yàn)樗饕某叽缦鄬τ贐樹索引來說小了很多。因?yàn)檫@些索引是低基數(shù)的B樹索引,所以非常小,因此您可以經(jīng)常檢索表中超過半數(shù)的行,并且仍使用位圖索引。
??當(dāng)大多數(shù)條目不會向位圖添加新的值時,位圖索引在批處理(單用戶)操作中加載表(插入操作)方面通常要比B樹做得好。當(dāng)多個會話同時向表中插入行時不應(yīng)該使用位圖索引,在大多數(shù)事務(wù)處理應(yīng)用程序中都會發(fā)生這種情況。
??在一個查詢中合并多個位圖索引后,可以使性能顯著提高。位圖索引使用固定長度的數(shù)據(jù)類型要比可變長度的數(shù)據(jù)類型好。較大尺寸的塊也會提高對位圖索引的存儲和讀取性能。

3、 反向索引

??這個索引不常見,但是特定情況特別有效,比如一個varchar(5)位字段(員工編號)含值
(10001,10002,10033,10005,10016…)
這種情況默認(rèn)索引分布過于密集,不能利用好服務(wù)器的并行
但是反向之后10001,20001,33001,50001,61001就有了一個很好的分布,能高效的利用好并行運(yùn)算。

(1)特點(diǎn):

??不可以將反轉(zhuǎn)鍵索引與位圖索引或索引組織表結(jié)合使用。因?yàn)椴荒軐ξ粓D索引和索引組織表進(jìn)行反轉(zhuǎn)鍵處理。

(2)技巧:

??如果您的磁盤容量有限,同時還要執(zhí)行大量的有序載入,就可以使用反轉(zhuǎn)鍵索引。

4、HASH索引

??使用HASH索引必須要使用HASH集群。建立一個集群或HASH集群的同時,也就定義了一個集群鍵。這個鍵告訴Oracle如何在集群上存儲表。在存儲數(shù)據(jù)時,所有與這個集群鍵相關(guān)的行都被存儲在一個數(shù)據(jù)庫塊上。如果數(shù)據(jù)都存儲在同一個數(shù)據(jù)庫塊上,并且將HASH索引作為WHERE子句中的確切匹配,Oracle就可以通過執(zhí)行一個HASH函數(shù)和I/O來訪問數(shù)據(jù)——而通過使用一個二元高度為4的B樹索引來訪問數(shù)據(jù),則需要在檢索數(shù)據(jù)時使用4個I/O。其中的查詢是一個等價查詢,用于匹配HASH列和確切的值。Oracle可以快速使用該值,基于HASH函數(shù)確定行的物理存儲位置。
??HASH索引可能是訪問數(shù)據(jù)庫中數(shù)據(jù)的最快方法,但它也有自身的缺點(diǎn)。集群鍵上不同值的數(shù)目必須在創(chuàng)建HASH集群之前就要知道。需要在創(chuàng)建HASH集群的時候指定這個值。低估了集群鍵的不同值的數(shù)字可能會造成集群的沖突(兩個集群的鍵值擁有相同的HASH值)。這種沖突是非常消耗資源的。沖突會造成用來存儲額外行的緩沖溢出,然后造成額外的I/O。如果不同HASH值的數(shù)目已經(jīng)被低估,您就必須在重建這個集群之后改變這個值。
??ALTER CLUSTER命令不能改變HASH鍵的數(shù)目。HASH集群還可能浪費(fèi)空間。如果無法確定需要多少空間來維護(hù)某個集群鍵上的所有行,就可能造成空間的浪費(fèi)。如果不能為集群的未來增長分配好附加的空間,HASH集群可能就不是最好的選擇。如果應(yīng)用程序經(jīng)常在集群表上進(jìn)行全表掃描,HASH集群可能也不是最好的選擇。由于需要為未來的增長分配好集群的剩余空間量,全表掃描可能非常消耗資源。
在實(shí)現(xiàn)HASH集群之前一定要小心。您需要全面地觀察應(yīng)用程序,保證在實(shí)現(xiàn)這個選項(xiàng)之前已經(jīng)了解關(guān)于表和數(shù)據(jù)的大量信息。通常,HASH對于一些包含有序值的靜態(tài)數(shù)據(jù)非常有效。

(1)特點(diǎn):

??可以在表中創(chuàng)建基于函數(shù)的索引。如果沒有基于函數(shù)的索引,任何在列上執(zhí)行了函數(shù)的查詢都不能使用這個列的索引。例如,下面的查詢就不能使用JOB列上的索引,除非它是基于函數(shù)的索引:

select * from emp where UPPER(job) = 'MGR';

下面的查詢使用JOB列上的索引,但是它將不會返回JOB列具有Mgr或mgr值的行:

select * from emp where job = 'MGR';

??可以創(chuàng)建這樣的索引,允許索引訪問支持基于函數(shù)的列或數(shù)據(jù)。可以對列表達(dá)式UPPER(job)創(chuàng)建索引,而不是直接在JOB列上建立索引,如:

create index EMP$UPPER_JOB on emp(UPPER(job));

??盡管基于函數(shù)的索引非常有用,但在建立它們之前必須先考慮下面一些問題:
能限制在這個列上使用的函數(shù)嗎?如果能,能限制所有在這個列上執(zhí)行的所有函數(shù)嗎
??是否有足夠應(yīng)付額外索引的存儲空間?
??在每列上增加的索引數(shù)量會對針對該表執(zhí)行的DML語句的性能帶來何種影響?
??基于函數(shù)的索引非常有用,但在實(shí)現(xiàn)時必須小心。在表上創(chuàng)建的索引越多,INSERT、UPDATE和DELETE語句的執(zhí)行就會花費(fèi)越多的時間。

5、函數(shù)索引

??可以在表中創(chuàng)建基于函數(shù)的索引。如果沒有基于函數(shù)的索引,任何在列上執(zhí)行了函數(shù)的查詢都不能使用這個列的索引。例如,下面的查詢就不能使用JOB列上的索引,除非它是基于函數(shù)的索引:

select * from emp where UPPER(job) = 'MGR';

下面的查詢使用JOB列上的索引,但是它將不會返回JOB列具有Mgr或mgr值的行:

select * from emp where job = 'MGR';

??可以創(chuàng)建這樣的索引,允許索引訪問支持基于函數(shù)的列或數(shù)據(jù)。可以對列表達(dá)式UPPER(job)創(chuàng)建索引,而不是直接在JOB列上建立索引,如:

create index EMP$UPPER_JOB on emp(UPPER(job));

盡管基于函數(shù)的索引非常有用,但在建立它們之前必須先考慮下面一些問題:
??能限制在這個列上使用的函數(shù)嗎?如果能,能限制所有在這個列上執(zhí)行的所有函數(shù)嗎
??是否有足夠應(yīng)付額外索引的存儲空間?
??在每列上增加的索引數(shù)量會對針對該表執(zhí)行的DML語句的性能帶來何種影響?
基于函數(shù)的索引非常有用,但在實(shí)現(xiàn)時必須小心。在表上創(chuàng)建的索引越多,INSERT、UPDATE和DELETE語句的執(zhí)行就會花費(fèi)越多的時間。

6、分區(qū)索引和全局索引

??分區(qū)索引就是簡單地把一個索引分成多個片斷。通過把一個索引分成多個片斷,可以訪問更小的片斷(也更快),并且可以把這些片斷分別存放在不同的磁盤驅(qū)動器上(避免I/O問題)。B樹和位圖索引都可以被分區(qū),而HASH索引不可以被分區(qū)。可以有好幾種分區(qū)方法:表被分區(qū)而索引未被分區(qū);表未被分區(qū)而索引被分區(qū);表和索引都被分區(qū)。不管采用哪種方法,都必須使用基于成本的優(yōu)化器。分區(qū)能夠提供更多可以提高性能和可維護(hù)性的可能性
有兩種類型的分區(qū)索引:本地分區(qū)索引和全局分區(qū)索引。每個類型都有兩個子類型,有前綴索引和無前綴索引。表各列上的索引可以有各種類型索引的組合。如果使用了位圖索引,就必須是本地索引。把索引分區(qū)最主要的原因是可以減少所需讀取的索引的大小,另外把分區(qū)放在不同的表空間中可以提高分區(qū)的可用性和可靠性。
??在使用分區(qū)后的表和索引時,Oracle還支持并行查詢和并行DML。這樣就可以同時執(zhí)行多個進(jìn)程,從而加快處理這條語句。
??可以使用與表相同的分區(qū)鍵和范圍界限來對本地索引分區(qū)。每個本地索引的分區(qū)只包含了它所關(guān)聯(lián)的表分區(qū)的鍵和ROWID。本地索引可以是B樹或位圖索引。如果是B樹索引,它可以是唯一或不唯一的索引。
??這種類型的索引支持分區(qū)獨(dú)立性,這就意味著對于單獨(dú)的分區(qū),可以進(jìn)行增加、截取、刪除、分割、脫機(jī)等處理,而不用同時刪除或重建索引。Oracle自動維護(hù)這些本地索引。本地索引分區(qū)還可以被單獨(dú)重建,而其他分區(qū)不會受到影響。

7、域索引 Domain

??域索引實(shí)際為用戶自定義索引,域索引主要對存儲在數(shù)據(jù)庫中的媒體,圖像數(shù)據(jù)進(jìn)行索引,這些數(shù)據(jù)在oracle中基本上以BLOB類型存儲,不同的應(yīng)用存儲格式也不同,oracle不可能提供某一種現(xiàn)成的算法對這些數(shù)據(jù)進(jìn)行索引,為了能夠?qū)@些類型數(shù)據(jù)快速訪問,oracle提供了現(xiàn)成的接口函數(shù),用戶可以針對自己的數(shù)據(jù)格式實(shí)現(xiàn)這些接口函數(shù),以達(dá)到對這些數(shù)據(jù)的快速訪問。

四、怎樣建立索引

CREATE UNIQUE | BITMAP INDEX <schema>.<index_name>ON <schema>.<table_name>(<column_name> | <expression> ASC | DESC,<column_name> | <expression> ASC | DESC,...)TABLESPACE <tablespace_name>STORAGE <storage_settings>LOGGING | NOLOGGINGCOMPUTE STATISTICSNOCOMPRESS | COMPRESS<nn>NOSORT | REVERSEPARTITION | GLOBAL PARTITION<partition_setting>

UNIQUE | BITMAP:指定UNIQUE為唯一值索引,BITMAP為位圖索引,省略為B-Tree索引。
<column_name> | <expression> ASC | DESC:可以對多列進(jìn)行聯(lián)合索引,當(dāng)為expression時即“基于函數(shù)的索引”
TABLESPACE:指定存放索引的表空間(索引和原表不在一個表空間時效率更高)
STORAGE:可進(jìn)一步設(shè)置表空間的存儲參數(shù)
LOGGING | NOLOGGING:是否對索引產(chǎn)生重做日志(對大表盡量使用NOLOGGING來減少占用空間并提高效率)
COMPUTE STATISTICS:創(chuàng)建新索引時收集統(tǒng)計(jì)信息
NOCOMPRESS | COMPRESS<nn>:是否使用“鍵壓縮”(使用鍵壓縮可以刪除一個鍵列中出現(xiàn)的重復(fù)值)
NOSORT | REVERSE:NOSORT表示與表中相同的順序創(chuàng)建索引,REVERSE表示相反順序存儲索引值
PARTITION | NOPARTITION:可以在分區(qū)表和未分區(qū)表上對創(chuàng)建的索引進(jìn)行分區(qū)

1、普通索引

create index index_text_txt on test(txt);

2、唯一索引

create unique index <index_name> on <table_name>(<coiumn_name>);

3、位圖索引

create bitmap index <index_name> on <table_name>(<column_name>)

4、組合索引

create index <index_name> on <table_name>(<column_name1><column_name2>)

5、基于函數(shù)索引

create index <index_name> on <table_name>(column_name) reverse; create index <index_name> on <table_name>(upper(column_name))

6、反向鍵索引

create index <index_name> on <table_name>(column_name) reverse;

7.重置索引

alter index <index_name> rebuild;

8.刪除索引

drop index <index_name>

五、索引失效細(xì)節(jié)

1.使用不等于操作符(<>, !=)

??下面這種情況,即使在列dept_id有一個索引,查詢語句仍然執(zhí)行一次全表掃描

select * from dept where staff_num <> 1000;

??但是開發(fā)中的確需要這樣的查詢,難道沒有解決問題的辦法了嗎?
??有!
??通過把用 or 語法替代不等號進(jìn)行查詢,就可以使用索引,以避免全表掃描:上面的語句改成下面這樣的,就可以使用索引了。

select * from dept shere staff_num < 1000 or dept_id > 1000;

2.使用 is null 或 is not null

??使用 is null 或is nuo null也會限制索引的使用,因?yàn)閿?shù)據(jù)庫并沒有定義null值。如果被索引的列中有很多null,就不會使用這個索引(除非索引是一個位圖索引,關(guān)于位圖索引,會在以后的blog文章里做詳細(xì)解釋)。在sql語句中使用null會造成很多麻煩。
解決這個問題的辦法就是:建表時把需要索引的列定義為非空(not null)

3.使用函數(shù)

??如果沒有使用基于函數(shù)的索引,那么where子句中對存在索引的列使用函數(shù)時,會使優(yōu)化器忽略掉這些索引。下面的查詢就不會使用索引:

select * from staff where trunc(birthdate) = '01-MAY-82';

??但是把函數(shù)應(yīng)用在條件上,索引是可以生效的,把上面的語句改成下面的語句,就可以通過索引進(jìn)行查找。

select * from staff where birthdate < (to_date('01-MAY-82') + 0.9999);

4.比較不匹配的數(shù)據(jù)類型

??比較不匹配的數(shù)據(jù)類型也是難于發(fā)現(xiàn)的性能問題之一。下面的例子中,dept_id是一個varchar2型的字段,在這個字段上有索引,但是下面的語句會執(zhí)行全表掃描。

select * from dept where dept_id = 900198;

??這是因?yàn)閛racle會自動把where子句轉(zhuǎn)換成to_number(dept_id)=900198,就是3所說的情況,這樣就限制了索引的使用。把SQL語句改為如下形式就可以使用索引

select * from dept where dept_id = '900198';

5.使用like子句

??使用like子句查詢時,數(shù)據(jù)需要把所有的記錄都遍歷來進(jìn)行判斷,索引不能發(fā)揮作用,這種情況也要盡量避免。
Like 的字符串中第一個字符如果是‘%’則用不到索引
Column1 like ‘a(chǎn)aa%’ 是可以的
Column1 like ‘%aaa%’用不到

6.使用in

??盡管In寫法要比exists簡單一些,exists一般來說性能要比In要高的多
用In還是用Exists的時機(jī),當(dāng)in的集合比較小的時候,或者用Exists無法用到選擇性高的索引的時候,用In要好,否則就要用Exists
例:

select count(*) from person_info where xb in (select xb_id from dic_sex); Select count(*) from n_acntbasic a where shbxdjm =:a and exists(select 1 from person_info where pid=a.pid and);Select * from person_info where zjhm=3101.;將會對person_info全表掃描 Select * from person_info where zjhm =3101…’才能用到索引

??假定TEST表的dt字段是date類型的并且對dt建了索引。
??如果要查‘20041010’一天的數(shù)據(jù).下面的方法用不到索引

Select * from test where to_char(dt,’yyyymmdd’) =20041010;select * from test where dt >=to_date(20041010,’yyyymmdd’) and dt < to_date(20041010,’yyyymmdd’) + 1 將會用到索引。

7.如果能不用到排序,則盡量避免排序

??用到排序的情況有集合操作。Union ,minus ,intersect等,注:union all 是不排序的。Order by、Group by、Distinct、In 有時候也會用到排序,確實(shí)要排序的時候也盡量要排序小數(shù)據(jù)量,盡量讓排序在內(nèi)存中執(zhí)行,有文章說,內(nèi)存排序的速度是硬盤排序的1萬倍。

總結(jié)

以上是生活随笔為你收集整理的Oracle索引详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。