b樹索引是Oracle中的通用索引,是創建索引時的默認索引類型。您最多可以包含32列。
位圖索引Oracle為每個唯壹鍵創建壹個位圖,然後將與鍵值關聯的ROWID保存為位圖。您最多可以包含30列。
壹般來說,大多數用戶只創建普通類型的B樹索引,所以我們不為基數較低的列創建索引,因為B樹索引可能不會提高查詢速度,甚至會增加Insert、Update和Delete命令消耗的時間。
在加載表(插入操作)時,位圖索引通常比B樹索引做得更好。通常,位圖索引在低基數上比B樹索引快3~4倍(幾個不同的值),但如果新添加的值占插入行的70%以上,B樹索引通常更快。當向每個記錄添加新值時,B樹索引比位圖索引快三倍。
不建議在某些在線事務處理(OLTP)應用程序中使用位圖索引。B樹索引的索引值包含ROWID,這樣Oracle可以在行級別鎖定索引。位圖索引存儲為壓縮的索引值,其中包含壹個範圍內的rowid,因此ORACLE必須為給定值鎖定所有範圍內的rowid。這種鎖定可能會在某些DML語句中導致死鎖。SELECT語句不受此鎖定問題的影響。
位圖索引有許多限制:
1.基於規則的優化器不會考慮位圖索引。
2.當執行ATLER TABLE語句並修改包含位圖索引的列時,位圖索引將生效。
3.位圖索引將索引鍵值存儲在索引塊中;但是,他們不能使用任何類型的完整性檢查。
4.位圖索引不能聲明為唯壹索引。
以上是引用的壹些簡單概念,以下是我從實際工作中總結出來的:
我想做壹個查詢,涉及兩個表T _ sym _ dict和T _ sym _ operlog。表格結構如下:
oracle的索引使用Oracle的索引來使用。
t_sym_operlog的索引如下:
Oracle的索引使用
上面基數相對較小的三列創建位圖索引。
t_sym_dict的索引如下:
Oracle的索引使用
查詢語句如下:
選擇(選擇c.dict_name
從t_sym_dict c
其中c.dict_typeid = 'SYM城市信息'
和c.dict_id = t.memo)分支,
T.staff_id工作編號
從t_sym_operlog t
其中t.operlog_subtype = '103 '
並且t.obj_type = 'CUSTLINKINFO '
t.memo = '200 '
-並且t.extsys_code = ' '
-而t.staff_id = ' '
和t.oper _ date & gt= to _ date(' 20110501000000 ',' yyyymmddhh24miss ')
和t.oper _ date & lt= to _ date(' 20110530000000 ',' yyyymmddhh24miss ')
-按t.memo,t.oper_date訂購
然後就出現了下面這個奇怪的現象(創建指數沒有問題)
1,索引正常使用。
Oracle的索引使用
2.下面看不到oper_date索引的用法。
Oracle的索引使用
3.下面無法看到表t_sym_operlog的索引用法。
Oracle的索引使用
嘗試的解決方案:
收集數據表就是分析。
開始
DBMS _ stats . gather _ table _ stats(own name = & gt;' CSID ',tabname = & gtt _ sym _ oper log _ back ');
結束;
猜測的原因:
當妳使用SQL語言向數據庫發布查詢語句時,ORACLE會產生壹個“執行計劃”,即使用什麽數據搜索方案來執行語句,是通過全表掃描還是索引搜索。搜索方案的選擇與ORACLE optimizer密切相關。
SQL語句的執行步驟
SQL語句的處理經歷以下步驟。
1語法分析分析語句的語法是否符合規範,衡量語句中每個表達式的含義。
語義分析檢查語句涉及的所有數據庫對象是否存在,用戶是否有相應的權限。
3視圖轉換將涉及視圖的查詢語句轉換為基表上相應的查詢語句。
4表達式轉換將復雜的SQL表達式轉換為更簡單的等效連接表達式。
5選擇優化器不同的優化器通常會產生不同的“執行計劃”
6選擇連接方式ORACLE有三種連接方式,多表連接ORACLE可以選擇合適的連接方式。
7選擇連接多個表的連接順序。ORACLE選擇先連接哪對表,並將兩個表中的哪壹個用作源數據表。
8選擇數據的搜索路徑根據以上條件選擇合適的數據搜索路徑,如全表搜索、索引或其他方法。
9運行“執行計劃”
分析:
oracle優化器CBO的典型問題:
有時候顯示有索引,但是查詢過程中明顯沒有用到相關索引,導致查詢過程漫長,資源巨大。有什麽問題?按照下面的順序,基本可以找到原因。
查找原因的步驟
首先我們需要確定數據庫運行在哪個優化模式下,對應的參數是:optimizer_mode。可以在svrmgrl中運行“show parameter optimizer_mode”來查看。從ORACLE V7開始,默認設置應該是“choose”,即查詢被分析表時選擇CBO,否則選擇RBO。如果該參數設置為“rule”,則無論表是否經過分析,都將選擇RBO,除非在語句中使用hint來強制執行它。
其次,檢查PL/SQL語句的WHERE子句中是否出現了索引列或復合索引的第壹列,這是“執行計劃”在相關索引中使用的必要條件。
第三,看采用什麽類型的連接。ORACLE的* * *包括排序合並連接(SMJ)、散列連接(HJ)和嵌套循環連接(NL)。當兩個表相連接並且內部表的目標列上有索引時,只有嵌套循環可以有效地使用索引。即使相關列上有索引,SMJ最多也只能因為索引的存在而避開數據排序過程。因為HJ要做哈希運算,索引的存在對數據查詢的速度影響不大。
第四,看連接順序是否允許使用相關索引。假設表emp的deptno列上有索引,表dept的deptno列上沒有索引,WHERE語句有EMP的條件。Deptno = Dept.Deptno .進行NL連接時,emp作為外觀首先被訪問。由於連接機制,外觀的數據訪問方式是全表掃描,顯然不需要emp.deptno上的索引。最多可以對其進行全索引掃描或快速全索引掃描。
第五,是否使用系統數據字典表或視圖。因為沒有對系統數據字典表進行分析,可能會導致“執行計劃”非常差。但不要擅自分析數據字典表,否則可能導致死鎖或系統性能下降。
第六,索引列是否是函數的參數。如果是這樣,則查詢中不使用該索引。
第七,是否存在潛在的數據類型轉換。如果將字符型數據與數值型數據進行比較,ORACLE會自動用to_number()函數對字符型數據進行轉換,從而導致第六種現象的發生。
第八,是否為表和相關索引收集了足夠的統計數據。對於數據經常被添加、刪除和更改的表,最好定期對表進行分析和索引。SQL語句“分析表xxxx中所有索引的計算機統計信息;”。甲骨文只有掌握了充分反映現實的統計數據,才能做出正確的選擇。
第九,索引列的選擇性不高。
我們假設壹個典型的情況,有壹個表emp,* *有壹百萬行數據,但是emp.deptno列只有四個不同的值,比如10,20,30,40。雖然有許多emp數據行,但ORACLE默認表中列出的值均勻分布在所有數據行中,這意味著每個deptno值都有250,000個數據行與之對應。假設SQL搜索條件DEPTNO=10,使用DEPTNO列上的索引進行數據搜索的效率往往不會高於全表掃描。甲骨文自然對指數“視而不見”,認為指數沒有選擇性。
但是讓我們考慮另壹種情況。如果壹百萬行數據實際上不是均勻分布在deptno的四個值中,其中,990,000行對應於值10,5,000行對應於值20,300行對應於值30,200行對應於值40。在這種數據分布模式下,毫無疑問,如果可以應用索引,那麽在搜索除10以外的其他deptno值時,效率會高很多。我們可以單獨分析索引列,或者用analyze語句為該列構建直方圖,為該列收集足夠的統計數據,這樣ORACLE在搜索選擇性高的值時就可以使用索引。
第十,索引列值是否可以為空。如果索引列值可以為null,那些需要在SQL語句中返回NULL值的操作將不會使用索引,比如COUNT(*),而是掃描整個表。這是因為存儲在索引中的值不能完全為空。
第十壹,看是否使用了並行查詢(PQO)。並行查詢不會使用索引。
第十二,看PL/SQL語句中是否使用了綁定變量。因為數據庫不知道bind變量的具體值,所以在進行不等連接時,比如“
如果不能從以上幾個方面找出原因,那就只好通過在語句中添加hint來迫使ORACLE使用最優的“執行計劃”了。
提示采用註釋的方式,包括行註釋和段註釋。
如果我們想使用表A的IND_COL1索引,我們可以使用以下方法:
" SELECT * FROM A WHERE col 1 = XXX;"
註意,註釋字符必須跟在SELECT後面,註釋中的“+”應該緊跟在註釋起始符“/*”或“-”後面,否則hint會被認為是壹般的註釋,對PL/SQL語句的執行沒有影響。
兩種有效的跟蹤和調試方法
ORACLE提供了兩個有效的工具來跟蹤和調試PL/SQL語句的執行計劃。
壹種是解釋表模式。用戶首先要在自己的SCHEMA中創建壹個PLAN_TABLE表,執行計劃的每壹步都會記錄在表中。創建該表的SQL腳本是${ORACLE_HOME}/rdbms/admin/下的utlxplan.sql。
打開SQL*PLUS,輸入“SET AUTOTRACE ON”,然後運行要調試的SQL語句。查詢結果給出後,ORACLE會顯示相應的“執行計劃”,包括優化器類型、執行成本、連接模式、連接順序、數據搜索路徑以及相應的資源成本如連續讀取、物理讀取等。
如果我們不能確定需要跟蹤的具體SQL語句,比如壹個應用使用壹段時間後,響應速度突然變慢。這時,我們可以使用ORACLE提供的另壹個強大的工具TKPROF來跟蹤應用程序的整個執行過程。
我們應該先根據USERID或者MACHINE在system view V$SESSION中找出對應的SID和SERIAL#。
將數據庫與SYS或其他執行過DBMS_SYSTEM包的用戶連接,執行“執行DBMS _ system。Set _ SQL _ trace _ in _ session (SID,SERIAL#,true)”。。
然後運行應用程序。此時在服務器端,在數據庫參數“USER_DUMP_DEST”指示的目錄下,會生成ora__xxxx.trc文件,其中xxxx是被跟蹤應用的操作系統進程號。
執行應用程序後,使用命令tkprof分析文件。命令示例:“tkprof跟蹤文件輸出文件explain = userid/password”。在操作系統ORACLE用戶下,輸入“tkprof”,會有詳細的命令幫助。分析後的outputfile包含每個PL/SQL語句的“執行計劃”、CPU使用率、物理讀取次數、邏輯讀取次數、執行持續時間等重要信息。根據輸出文件中的信息,我們可以快速找出應用程序中哪個PL/SQL語句是問題的癥結所在。