Oracle-index索引解读
概述
Oracle-OLAP和OLTP解讀
Oracle-index索引解讀
Oracle-分區(qū)表解讀
Oracle-鎖解讀
Oracle-等待事件解讀
Oracle-procedure/cursor解讀
索引是數(shù)據(jù)庫對象之一,用于加快數(shù)據(jù)的檢索
索引是建立在表上的可選對象;索引的關鍵在于通過一組排序后的索引鍵來取代默認的全表掃描檢索方式,索引直接指向包含所查詢值的行的位置,減少磁盤I/O,,從而提高檢索效率
索引在邏輯上和物理上都與相關的表和數(shù)據(jù)無關,當創(chuàng)建或者刪除一個索引時,不會影響基本的表,與所索引的表是相互獨立的物理結(jié)構(gòu)
索引一旦建立,Oracle 自動使用并維護索引,插入、刪除、更新表后,自動更新索引,不會對表產(chǎn)生影響.
索引對用戶是透明的,無論表上是否有索引,sql語句的用法不變
oracle創(chuàng)建主鍵時會自動在該列上創(chuàng)建索引
為什么需要索引
數(shù)據(jù)在磁盤上是以塊的形式存儲的。為確保對磁盤操作的原子性,訪問數(shù)據(jù)的時候會一并訪問所有數(shù)據(jù)塊。磁盤上的這些數(shù)據(jù)塊與鏈表類似,即它們都包含一個數(shù)據(jù)段和一個指針,指針指向下一個節(jié)點(數(shù)據(jù)塊)的內(nèi)存地址,而且它們都不需要連續(xù)存儲(即邏輯上相鄰的數(shù)據(jù)塊在物理上可以相隔很遠)。
鑒于很多記錄只能做到按一個字段排序,所以要查詢某個未經(jīng)排序的字段,就需要使用線性查找,即要訪問N/2個數(shù)據(jù)塊,其中N指的是一個表所涵蓋的所有數(shù)據(jù)塊。如果該字段是非鍵字段(也就是說,不包含唯一值),那么就要搜索整個表空間,即要訪問全部N個數(shù)據(jù)塊。
然而,對于經(jīng)過排序的字段,可以使用二分查找,因此只要訪問log2 N個數(shù)據(jù)塊。同樣,對于已經(jīng)排過序的非鍵字段,只要找到更大的值,也就不用再搜索表中的其他數(shù)據(jù)塊了。這樣一來,性能就會有實質(zhì)性的提升。
什么是索引
索引是對記錄按照多個字段進行排序的一種方式。對表中的某個字段建立索引會創(chuàng)建另一種數(shù)據(jù)結(jié)構(gòu),其中保存著字段的值,每個值又指向與它相關的記錄。這種索引的數(shù)據(jù)結(jié)構(gòu)是經(jīng)過排序的,因而可以對其執(zhí)行二分查找。
索引的缺點是占用額外的磁盤空間。所以如果為同一個表中的很多字段都建立索引,那這個文件可能會很快膨脹到文件系統(tǒng)規(guī)定的上限。
當對表中的數(shù)據(jù)進行增加、刪除和修改的時候,索引也要動態(tài)的維護,這樣就降低了數(shù)據(jù)的維護速度。
索引的原理
首先,來看一個示例數(shù)據(jù)庫表的模式:
注意:這里用char而不用varchar是為了精確地描述數(shù)據(jù)占用磁盤的大小。
這個示例數(shù)據(jù)庫中包含500萬行記錄,而且沒有建立索引。
接下來我們就分析針對這個表的兩個查詢:一個查詢使用id(經(jīng)過排序的鍵字段),另一個查詢使用firstName(未經(jīng)排序的非鍵字段)。
示例分析一
對于這個擁有r = 5 000 000條記錄的示例數(shù)據(jù)庫,在磁盤上要為每條記錄分配 R = (4+50+50+100)204字節(jié)的固定存儲空間(4個字段所占空間的總和)。
默認的數(shù)據(jù)庫塊大小為 B = 1024字節(jié)。于是,我們可計算出這個表的分塊因數(shù)為 bfr = (B/R) = 1024/204 = 5,即磁盤上每個數(shù)據(jù)塊保存5條記錄。那么,保存整個表所需的數(shù)據(jù)塊數(shù)就是 N = (r/bfr) = 5000000/5 = 1 000 000。
使用線性查找搜索id字段——這個字段是鍵字段(每個字段的值唯一),需要訪問 N/2 = 500 000個數(shù)據(jù)塊才能找到目標值。不過,因為這個字段是經(jīng)過排序的,所以可以使用二分查找法,而這樣平均只需要訪問log2(1000000 )= 19.93 = 20 個塊。顯然,這會給性能帶來極大的提升。
再來看看firstName字段,這個字段是未經(jīng)排序的,因此不可能使用二分查找,況且這個字段的值也不是唯一的,所以要從表的開頭查找末尾,即要訪問 N = 1 000 000個數(shù)據(jù)塊。這種情況通過建立索引就能得到改善。
如果一條索引記錄只包含索引字段和一個指向原始記錄的指針,那么這條記錄肯定要比它所指向的包含更多字段的記錄更小。也就是說,索引本身占用的磁盤空間比原來的表更少,因此需要遍歷的數(shù)據(jù)塊數(shù)也比搜索原來的表更少。
以下是firstName字段索引的模式:
示例分析二
對于這個擁有r = 5 000 000條記錄的示例數(shù)據(jù)庫,每條索引記錄要占用 R = 54字節(jié)磁盤空間,而且同樣使用默認的數(shù)據(jù)塊大小 B = 1024字節(jié)。那么索引的分塊因數(shù)就是 bfr = (B/R) = 1024/54 = 18。最終這個表的索引需要占用 N = (r/bfr) = 5000000/18 = 277 778個數(shù)據(jù)塊。
現(xiàn)在,再搜索firstName字段就可以使用索引來提高性能了。對索引使用二分查找,需要訪問 log2 277778 = 18.09 = 19個數(shù)據(jù)塊。再加上為找到實際記錄的地址還要訪問一個數(shù)據(jù)塊,總共要訪問 19 + 1 = 20個數(shù)據(jù)塊,這與搜索未索引的表需要訪問277 778個數(shù)據(jù)塊相比,不啻于天壤之別。
什么時候用索引
創(chuàng)建索引要額外占用磁盤空間(比如,上面例子中要額外占用277 778個數(shù)據(jù)塊),建立的索引太多可能導致磁盤空間不足。因此,在建立索引時,一定要慎重選擇正確的字段。
由于索引只能提高搜索記錄中某個匹配字段的速度,因此在執(zhí)行插入和刪除操作的情況下,僅為輸出結(jié)果而為字段建立索引,就純粹是浪費磁盤空間和處理時間了;這種情況下不用建立索引。
另外,由于二分查找的原因,數(shù)據(jù)的基數(shù)性(cardinality)或唯一性也非常重要。對基數(shù)性為2的字段建立索引,會將數(shù)據(jù)一分為二,而對基數(shù)性為1000的字段,則同樣會返回大約1000條記錄。在這么低的基數(shù)性下,索引的效率將減低至線性查找的水平,而查詢優(yōu)化器會在基數(shù)性小于記錄數(shù)的30%時放棄索引,實際上等于索引純粹只會浪費空間。
另外需要說明: 創(chuàng)建了索引并不一定就會使用,oracle自動統(tǒng)計表的信息后,決定是否使用索引,表中數(shù)據(jù)很少時使用全表掃描速度已經(jīng)很快,沒有必要使用索引
索引的語法
創(chuàng)建索引
CREATE UNIUQE | 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>參數(shù)說明:
1) UNIQUE | BITMAP:指定UNIQUE為唯一值索引,BITMAP為位圖索引,省略為B-Tree索引。
2)<column_name> | <expression> ASC |
DESC:可以對多列進行聯(lián)合索引,當為expression時即“基于函數(shù)的索引”3)TABLESPACE:指定存放索引的表空間(索引和原表不在一個表空間時效率更高)
4)STORAGE:可進一步設置表空間的存儲參數(shù)
5)LOGGING | NOLOGGING:是否對索引產(chǎn)生重做日志(對大表盡量使用NOLOGGING來減少占用空間并提高效率)
6)COMPUTE STATISTICS:創(chuàng)建新索引時收集統(tǒng)計信息
7)NOCOMPRESS | COMPRESS<nn>:是否使用“鍵壓縮”(使用鍵壓縮可以刪除一個鍵列中出現(xiàn)的重復值)
8)NOSORT | REVERSE:NOSORT表示與表中相同的順序創(chuàng)建索引,REVERSE表示相反順序存儲索引值
9)PARTITION | NOPARTITION:可以在分區(qū)表和未分區(qū)表上對創(chuàng)建的索引進行分區(qū)
修改索引
重命名索引
alter index index_sno rename to bitmap_index;合并索引
表使用一段時間后在索引中會產(chǎn)生碎片,此時索引效率會降低,可以選擇重建索引或者合并索引,合并索引方式更好些,無需額外存儲空間,代價較低
alter index index_sno coalesce;重建索引
方式一:刪除原來的索引,重新建立索引
方式二:使用rebuild方式
alter index index_sno rebuild [online];rebuild 和 rebuild online的區(qū)別
alter index rebuild online:實質(zhì)上是掃描表而不是掃描現(xiàn)有的索引塊來實現(xiàn)索引的重建
alter index rebuild:只掃描現(xiàn)有的索引塊來實現(xiàn)索引的重建。
rebuild index online在執(zhí)行期間不會阻塞DML操作,但在開始和結(jié)束階段,需要請求模式為4的TM鎖。因此,如果在rebuild index online開始前或結(jié)束時,有其它長時間的事物在運行,很有可能就造成大量的鎖等待。也就是說在執(zhí)行前仍會產(chǎn)生阻塞, 應該避免排他鎖.
而rebuild index在執(zhí)行期間會阻塞DML操作, 但速度較快.
兩者重建索引時的掃描方式不同,
rebuild用的是“INDEX FAST FULL SCAN”,
rebuild online用的是“TABLE ACCESS FULL”;
即rebuild index是掃描索引塊,而rebuild index online是掃描全表的數(shù)據(jù)塊.
刪除索引
drop index index_sno;查看索引
查詢all_indexes select index_name, index_type, tablespace_name, uniquenessfrom all_indexeswhere table_name = 'tablename';或者查詢user_indexes select a.* from user_indexes a ;B樹索引的index_type為 NORMAL;而位圖索引的index_type類型值為BITMAP
索引分類
- B-樹索引(默認類型)
- 位圖索引
- HASH索引
- 索引編排表
- 反轉(zhuǎn)鍵索引
- 基于函數(shù)的索引
- 分區(qū)索引
- 本地和全局索引
B樹索引
說明
B樹索引在Oracle中是一個通用索引。在創(chuàng)建索引時它就是默認的索引類型。B樹索引可以是一個列的(簡單)索引,也可以是組合/復合(多個列)的索引。
B樹索引最多可以包括32列。
特點
1.oracle中最常用的索引;B樹索引就是一顆二叉樹;葉子節(jié)點(雙向鏈表)包含索引列和指向表中每個匹配行的ROWID值
2.所有葉子節(jié)點具有相同的深度,因而不管查詢條件怎樣,查詢速度基本相同
3.能夠適應精確查詢、模糊查詢和比較查詢
創(chuàng)建
B樹索引的單一索引
單一索引:
Create Index <Index-Name> On <Table_Name>(Column_Name)B樹索引的 復合索引
復合索引:
Create Index i_deptno_job on emp(deptno,job); —>在emp表的deptno、job列建立索引。 select * from emp where deptno=66 and job='sals' ->走索引。select * from emp where deptno=66 OR job='sals' ->將進行全表掃描。不走索引select * from emp where deptno=66 ->走索引。select * from emp where job='sals' ->進行全表掃描、不走索引。 如果在where 子句中有OR 操作符或單獨引用Job 列(索引列的后面列) 則將不會走索引,將會進行全表掃描。
即如果索引建立在多個列上,只有它的第一個列被where子句引用時,優(yōu)化器才會使用該索引,即至少要包含組合索引的第一列
適合使用場景
- 適合與大量的增、刪、改(OLTP)
- 不能用包含OR操作符的查詢;
- 列基數(shù)(列不重復值的個數(shù))大時適合使用B數(shù)索引
位圖索引
說明
創(chuàng)建位圖索引時,oracle會掃描整張表,并為索引列的每個取值建立一個位圖(位圖中,對表中每一行使用一位(bit,0或者1)來標識該行是否包含該位圖的索引列的取值,如果為1,表示對應的rowid所在的記錄包含該位圖索引列值),最后通過位圖索引中的映射函數(shù)完成位到行的ROWID的轉(zhuǎn)換.
位圖索引非常適合于決策支持系統(tǒng)(Decision Support System,DSS)和數(shù)據(jù)倉庫,它們不應該用于通過事務處理應用程序訪問的表。
它們可以使用較少到中等基數(shù)(不同值的數(shù)量)的列訪問非常大的表。
盡管位圖索引最多可達30個列,但通常它們都只用于少量的列。
比如:某個表可能包含一個稱為Sex的列,它有兩個可能值:男和女。這個基數(shù)只為2,如果用戶頻繁地根據(jù)Sex列的值查詢該表,這就是位圖索引的基列。當一個表內(nèi)包含了多個位圖索引時,您可以體會到位圖索引的真正威力。如果有多個可用的位圖索引,Oracle就可以合并從每個位圖索引得到的結(jié)果集,快速刪除不必要的數(shù)據(jù)。
特點
- 適合與決策支持系統(tǒng);
- 做UPDATE代價非常高;
- 非常適合OR操作符的查詢;
- 基數(shù)比較少的時候才能建位圖索引;
創(chuàng)建
例子:
Create bitmap Index <Index-Name> On <Table_Name>(Column_Name)適合使用場景
- 對于基數(shù)小的列適合建立位圖索引(例如性別等)
注意事項
建議不要在一些聯(lián)機事務處理(OLTP)應用程序中使用位圖索引。位圖索引的索引值中包含ROWID,這樣Oracle就可以在行級別上鎖定索引。
位圖索引存儲為壓縮的索引值,其中包含了一定范圍的ROWID,因此Oracle必須針對一個給定值鎖定所有范圍內(nèi)的ROWID。這種鎖定類型可能在某些DML語句中造成死鎖。
SELECT語句不會受到這種鎖定問題的影響。
基于規(guī)則的優(yōu)化器不會考慮位圖索引。
- 當執(zhí)行ALTER TABLE語句并修改包含有位圖索引的列時,會使位圖索引失效。
- 位圖索引不包含任何列數(shù)據(jù),并且不能用于任何類型的完整性檢查。
- 位圖索引不能被聲明為唯一索引。
- 位圖索引的最大長度為30。
函數(shù)索引
說明
當經(jīng)常要訪問一些函數(shù)或者表達式時,可以將其存儲在索引中,這樣下次訪問時,該值已經(jīng)計算出來了,可以加快查詢速度
函數(shù)索引既可以使用B樹索引,也可以使用位圖索引;當函數(shù)結(jié)果不確定時采用B樹索引,結(jié)果是固定的某幾個值時使用位圖索引
函數(shù)索引中可以使用len、trim、substr、upper(每行返回獨立結(jié)果),不能使用如sum、max、min、avg等
基于函數(shù)的索引非常有用,但在實現(xiàn)時必須小心。在表上創(chuàng)建的索引越多,INSERT、UPDATE和DELETE語句的執(zhí)行就會花費越多的時間。
創(chuàng)建
例子:
CREATE INDEX index ON table (FUNCTION(column));舉例: select * from student where upper(name) ='XGJ';分區(qū)索引
分區(qū)索引就是簡單地把一個索引分成多個片斷。通過把一個索引分成多個片斷,可以訪問更小的片斷(也更快),并且可以把這些片斷分別存放在不同的磁盤驅(qū)動器上(避免I/O問題)。
B樹和位圖索引都可以被分區(qū),而HASH索引不可以被分區(qū)。
可以有好幾種分區(qū)方法:表被分區(qū)而索引未被分區(qū);表未被分區(qū)而索引被分區(qū);表和索引都被分區(qū)。
不管采用哪種方法,都必須使用基于成本的優(yōu)化器。分區(qū)能夠提供更多可以提高性能和可維護性的可能性
有兩種類型的分區(qū)索引:本地分區(qū)索引和全局分區(qū)索引。
每個類型都有兩個子類型,有前綴索引和無前綴索引。表各列上的索引可以有各種類型索引的組合。如果使用了位圖索引,就必須是本地索引。
把索引分區(qū)最主要的原因是可以減少所需讀取的索引的大小,另外把分區(qū)放在不同的表空間中可以提高分區(qū)的可用性和可靠性。
在使用分區(qū)后的表和索引時,Oracle還支持并行查詢和并行DML。這樣就可以同時執(zhí)行多個進程,從而加快處理這條語句。
創(chuàng)建索引的一些規(guī)則
1. 權(quán)衡索引個數(shù)與DML之間關系,DML也就是插入、刪除數(shù)據(jù)操作。
這里需要權(quán)衡一個問題,建立索引的目的是為了提高查詢效率的,但建立的索引過多,會影響插入、刪除數(shù)據(jù)的速度,因為我們修改的表數(shù)據(jù),索引也要跟著修改。這里需要權(quán)衡我們的操作是查詢多還是修改多。
2. 把索引與對應的表放在不同的表空間。
當讀取一個表時表與索引是同時進行的。如果表與索引和在一個表空間里就會產(chǎn)生資源競爭,放在兩個表這空就可并行執(zhí)行。
3. 最好使用一樣大小的塊。
Oracle默認五塊,讀一次I/O,如果你定義6個塊或10個塊都需要讀取兩次I/O。最好是5的整數(shù)倍更能提高效率。
4. 如果一個表很大,建立索引的時間很長,因為建立索引也會產(chǎn)生大量的redo信息,所以在創(chuàng)建索引時可以設置不產(chǎn)生或少產(chǎn)生redo信息。只要表數(shù)據(jù)存在,索引失敗了大不了再建,所以可以不需要產(chǎn)生redo信息。
5. 建索引的時候應該根據(jù)具體的業(yè)務SQL來創(chuàng)建,特別是where條件,還有where條件的順序,盡量將過濾大范圍的放在后面,因為SQL執(zhí)行是從后往前的。
索引應該經(jīng)常建在Where 子句經(jīng)常用到的列上。如果某個大表經(jīng)常使用某個字段進行查詢,并且檢索行數(shù)小于總表行數(shù)的5%。則應該考慮。
6. 如果有兩個或者以上的索引,其中有一個唯一性索引,而其他是非唯一,這種情況下oracle將使用唯一性索引而完全忽略非唯一性索引
7. 至少要包含組合索引的第一列(即如果索引建立在多個列上,只有它的第一個列被where子句引用時,優(yōu)化器才會使用該索引)
8. 小表不要建立索引
9. 對于基數(shù)大的列適合建立B樹索引,對于基數(shù)小的列適合建立位圖索引
10. 列中有很多空值,但經(jīng)常查詢該列上非空記錄時應該建立索引
11. 經(jīng)常進行連接查詢的列應該創(chuàng)建索引
12. 使用create index時要將最常查詢的列放在最前面
13. LONG(可變長字符串數(shù)據(jù),最長2G)和LONG RAW(可變長二進制數(shù)據(jù),最長2G)列不能創(chuàng)建索引
14. 限制表中索引的數(shù)量(創(chuàng)建索引耗費時間,并且隨數(shù)據(jù)量的增大而增大;索引會占用物理空間;當對表中的數(shù)據(jù)進行增加、刪除和修改的時候,索引也要動態(tài)的維護,降低了數(shù)據(jù)的維護速度)
15 .對于兩表連接的字段,應該建立索引。如果經(jīng)常在某表的一個字段進行Order By 則也應該建立索引。
索引失效的情況
1.使用不等于操作符(not 、<>、!=)
oracle碰到not或者 <> !=會停止使用索引,而采用全表掃描
select * from student where not (score=100);select * from student where score <> 100;--替換為select * from student where score>100 or score <100通過把不等于操作符改成OR條件,就可以使用索引,以避免全表掃描。
2. 使用IS NULL 或IS NOT NULL
使用IS NULL 或IS NOT NULL同樣會限制索引的使用。
因為NULL值并沒有被定義。在SQL語句中使用NULL會有很多的麻煩。因此建議開發(fā)人員在建表時,把需要索引的列設成 NOT NULL。
如果被索引的列在某些行中存在NULL值,就不會使用這個索引(除非索引是一個位圖索引)。
索引上使用空值比較將停止使用索引.
3.使用函數(shù)
如果不使用基于函數(shù)的索引,那么在SQL語句的WHERE子句中對存在索引的列使用函數(shù)時,會使優(yōu)化器忽略掉這些索引。 下面的查詢不會使用索引(只要它不是基于函數(shù)的索引)
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);4.索引列上進行計算
索引列上不能進行計算
SELECT Col FROM tbl WHERE col / 10 > 10則會使索引失效,應該改成
SELECT Col FROM tbl WHERE col > 10 * 105.比較不匹配的數(shù)據(jù)類型
假設account_number是一個VARCHAR2類型,在account_number字段上有索引。
下面的語句將執(zhí)行全表掃描:
Oracle可以自動把where子句變成to_number(account_number)=990354,這樣就限制了索引的使用。
改成下面的查詢就可以使用索引:
select bank_name,address,city,state,zip from banks where account_number ='990354';特別注意:不匹配的數(shù)據(jù)類型之間比較會讓Oracle自動限制索引的使用,即便對這個查詢執(zhí)行Explain Plan也不能讓您明白為什么做了一次“全表掃描”。
6.通配符在搜索詞首出現(xiàn)時,oracle不能使用索引
--我們在name上創(chuàng)建索引;create index index_name on student('name');--下面的方式oracle不適用name索引select * from student where name like '%xgj%';--如果通配符出現(xiàn)在字符串的其他位置時,優(yōu)化器能夠利用索引;如下:select * from student where name like 'xgj%';7.用UNION替換OR(適用于索引列)
union:是將兩個查詢的結(jié)果集進行追加在一起,它不會引起列的變化。
由于是追加操作,需要兩個結(jié)果集的列數(shù)應該是相關的,并且相應列的數(shù)據(jù)類型也應該相當?shù)摹?/p>
union 返回兩個結(jié)果集,同時將兩個結(jié)果集重復的項進行消除。
如果不進行消除,用UNOIN ALL.
通常情況下, 用UNION替換WHERE子句中的OR將會起到較好的效果. 對索引列使用OR將造成全表掃描. 注意, 以上規(guī)則只針對多個索引列有效.
如果有column沒有被索引, 查詢效率可能會因為你沒有選擇OR而降低.
在下面的例子中, LOC_ID 和REGION上都建有索引.
高效:
SELECT LOC_ID , LOC_DESC , REGIONFROM LOCATIONWHERE LOC_ID = 10UNIONSELECT LOC_ID , LOC_DESC , REGIONFROM LOCATIONWHERE REGION = “MELBOURNE” 低效:
如果你堅持要用OR, 那就需要返回記錄最少的索引列寫在最前面.
8. 用EXISTS替代IN、用NOT EXISTS替代NOT IN
在許多基于基礎表的查詢中, 為了滿足一個條件, 往往需要對另一個表進行聯(lián)接. 在這種情況下, 使用EXISTS(或NOT EXISTS)通常將提高查詢的效率.
在子查詢中, NOT IN子句將執(zhí)行一個內(nèi)部的排序和合并.
無論在哪種情況下, NOT IN都是最低效的(因為它對子查詢中的表執(zhí)行了一個全表遍歷).
為了避免使用NOT IN, 我們可以把它改寫成外連接(Outer Joins)或NOT EXISTS.
例子:
高效:
SELECT * FROM EMP (基礎表) WHERE EMPNO > 0 AND EXISTS (SELECT ‘X’ FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = ‘MELB’)低效:
SELECT * FROM EMP (基礎表) WHERE EMPNO > 0 AND DEPTNO IN(SELECT DEPTNO FROM DEPT WHERE LOC = ‘MELB’)Sql優(yōu)化的一點建議
Sql 優(yōu)化:
當Oracle數(shù)據(jù)庫拿到SQL語句時,其會根據(jù)查詢優(yōu)化器分析該語句,并根據(jù)分析結(jié)果生成查詢執(zhí)行計劃。
也就是說,數(shù)據(jù)庫是執(zhí)行的查詢計劃,而不是Sql語句。
查詢優(yōu)化器有rule-based-optimizer(基于規(guī)則的查詢優(yōu)化器) 和Cost-Based-optimizer(基于成本的查詢優(yōu)化器)。
其中基于規(guī)則的查詢優(yōu)化器在10g版本中消失。
對于規(guī)則查詢,其最后查詢的是全表掃描。而CBO則會根據(jù)統(tǒng)計信息進行最后的選擇。
1、先執(zhí)行From ->Where ->Group By->Order By
2、執(zhí)行From 字句是從右往左進行執(zhí)行。因此必須選擇記錄條數(shù)最少的表放在右邊。
3、對于Where字句其執(zhí)行順序是從后向前執(zhí)行、因此可以過濾最大數(shù)量記錄的條件必須寫在Where子句的末尾,而對于多表之間的連接,則寫在之前。
因為這樣進行連接時,可以去掉大多不重復的項。4、SELECT子句中避免使用(*)ORACLE在解析的過程中, 會將’*’ 依次轉(zhuǎn)換成所有的列名, 這個工作是通過查詢數(shù)據(jù)字典完成的,這意味著將耗費更多的時間
總結(jié)
以上是生活随笔為你收集整理的Oracle-index索引解读的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Oracle-OLAP和OLTP解读
- 下一篇: Oracle-分区表解读