oracle有哪些索引
oracle的索引類型有:非唯一索引、唯一索引、點陣圖索引、局部有前綴分區索引、局部無前綴分區索引、全域有前綴分區索引、雜湊分區索引、基於函數的索引。索引需在表中插入資料後創建,唯一索引可用「create unique index」語句建立。
本教學操作環境:Windows7系統、Oracle 11g版、Dell G3電腦。
什麼是索引?
- 索引是建立在表格的一列或多個列上的輔助對象,目的是加快存取表中的資料;
- Oracle儲存索引的資料結構是B*樹(平衡樹),點陣圖索引也是如此,只不過是葉子節點不同B*數索引;
索引由根節點、分支節點和葉子節點組成,上級索引塊包含下級索引塊的索引數據,葉節點包含索引資料和確定行實際位置的rowid。
索引說明
1)索引是資料庫物件之一,用於加快資料的檢索,類似於書籍的索引。在資料庫中索引可以減少資料庫程式查詢結果時需要讀取的資料量,類似於在書籍中我們利用索引可以不用翻閱整本書即可找到想要的資訊。
2)索引是建立在表上的可選物件;索引的關鍵在於透過一組排序後的索引鍵來取代預設的全表掃描檢索方式,從而提高檢索效率
#3)索引在邏輯上和物理上都與相關的表和資料無關,當建立或刪除索引時,不會影響基本的表;
4)索引一旦建立,在表上進行DML操作時(例如執行插入、修改或刪除相關操作時),oracle會自動管理索引,索引刪除,不會對錶產生影響
5)索引對使用者是透明的,無論表上是否有索引,sql語句的用法不變
6)oracle在建立主鍵時會自動在該列上建立索引
使用索引的目的:
- 加快查詢速度
- 減少I/O操作
- 消除磁碟排序(索引能加快排序速度)
#何時使用索引:
- 查詢傳回的記錄數排序表<40%,對非排序表<7%
- 表格的碎片較多(頻繁增加、刪除)
#索引的類型
- ##非唯一索引(最常用)
- 唯一索引
- 位圖索引
- 局部有前綴分割索引
- 局部無前綴分割區索引
- 全域有前綴分割區索引
- 雜湊分區索引
管理索引的準則
- 在表中插入資料後建立索引
在用SQL*Loader或
import
索引正確的表格和欄位
- #經常會擷取排序大表中40%或非排序表7%的行,建議建索引;
- 為了改善多表關聯,索引列用於聯結;
- #列中的值相對比較唯一;
- 取值範圍(大:B*樹索引,小:位圖索引);
- Date型列一般適合基於函數的索引;
為效能而安排索引列
- #經常一起使用多個欄位檢索記錄,組合索引比單一索引更有效;
把最常用的列放在最前面,例:
dx_groupid_serv_id(groupid,serv_id)
,在where
條件中使用groupid
或groupid,serv_id
,查詢將使用索引,若僅用到 serv_id
合併/分割不必要的索引。
限制每個表索引的數量
- 一個表可以有數百個索引(你會這樣做嗎?) ,但對於頻繁插入和更新表,索引越多系統CPU,I/O負擔就越重;
- 建議每張表不超過5個索引。
刪除不再需要的索引
- #索引無效,集中表現在該使用基於函數的索引或位圖索引,而使用了B*樹索引;
- 應用程式中的查詢不使用索引;
- ##重建索引之前必須先刪除索引,若用alter index … rebuild重建索引,則不必刪除索引。
索引資料塊空間使用
###- 建立索引時指定表空間,特別是在建立主鍵時,應明確指定表空間;
- #合理設定pctfress,注意:不能給索引指定pctused;
- 估計索引的大小和合理地設定儲存參數,預設為表空間大小,或initial與next設定成一樣大。
考慮並行建立索引
- 對大表可以採用並行建立索引,在並行建立索引時,儲存參數被每個查詢伺服器行程分別使用,例如:
initial
為1M
,並行度為8
,則建立索引期間至少要消耗8M
空間;
考慮用nologging
建立索引
- #對大表建立索引可以使用nologging來減少重做日誌;
- 節省重做日誌檔案的空間;
- 縮短建立索引的時間;
- 改善了並行建立大索引時的效能。
怎麼建立最佳索引?
#明確地建立索引
create index index_name on table_name(field_name) tablespace tablespace_name pctfree 5 initrans 2 maxtrans 255 storage ( minextents 1 maxextents 16382 pctincrease 0 );
建立基於函數的索引:
常用與UPPER、LOWER、TO_CHAR(date)
等函數分類上,範例:
create index idx_func on emp (UPPER(ename)) tablespace tablespace_name;
建立位圖索引:
##對基底數較小,且基數相對穩定的列建立索引時,首先應該考慮位圖索引,例:create bitmap index idx_bitm on class (classno) tablespace tablespace_name;
- 語句來建立唯一索引,範例:
- 建立與約束相關的索引
- 可以用 using index
- 字句,為與 unique
create unique index dept_unique_idx on dept(dept_no) tablespace idx_1;
primary key
約束相關的欄位建立索引,例如:alter table table_name add constraint PK_primary_keyname primary key (field_name) using index tablespace tablespace_name;
##分區數量與基礎表相同;
Create Index TG_CDR04_SERV_ID_IDX On TG_CDR04(SERV_ID) Pctfree 5 Tablespace TBS_AK01_IDX Storage ( MaxExtents 32768 PctIncrease 0 FreeLists 1 FreeList Groups 1 ) local /
- 如何建立範圍分區的全域索引基礎表可以是全域表和分區表。
create index idx_start_date on tg_cdr01(start_date) global partition by range(start_date) (partition p01_idx vlaues less than (‘0106’) partition p01_idx vlaues less than (‘0111’) … partition p01_idx vlaues less than (‘0401’ )) /
登入後複製 重建現存的索引- 重建現存的索引的當前時刻不會影響查詢;
- 重建索引可以刪除額外的資料塊; 提高索引查詢效率;
- #
alter index idx_name rebuild nologging;
登入後複製 對於分割索引: alter index idx_name rebuild partition partiton_name nologging;
登入後複製要刪除索引的原因<br/><br/><br/>不再需要的索引;
索引沒有針對其相關的表所發佈的查詢提供所期望的效能改善;
應用程式沒有用該索引來查詢資料;該索引無效,必須在重建之前刪除該索引;這個索引已經變的太碎了,必須在重建之前刪除該索引;
語句:
drop index idx_name; drop index idx_name drop partition partition_name;
建立索引的代價#基礎表維護時,系統要同時維護索引,不合理的索引將嚴重影響系統資源,主要表現在CPU和I/O上;
插入、更新、刪除資料產生大量db file sequential read鎖定等待;一個表格中有數百萬條數據,對某個字段加了索引,但是查詢時性能並沒有什麼提高,這主要可能是
oracle的索引限製造成的。
oracle的索引有一些索引限制,在這些索引限制發生的情況下,即使已經加了索引,oracle
還是會執行一次全表掃描,查詢的效能不會比不加索引有所提高,反而可能由於資料庫維護索引的系統開銷造成效能更差。
擴充知識:常見的索引限制問題
#1、使用不等於運算子(<>, != )
下面這種情況,即使在列dept_id
有一個索引,查詢語句仍然執行一次全表掃描<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>select * from dept where staff_num <> 1000;</pre><div class="contentsignin">登入後複製</div></div>
但是開發中的確需要這樣的查詢,難道沒有解決問題的方法了嗎? 有!
透過把用 or 語法取代不等號來查詢,就可以使用索引,以避免全表掃描:上面的語句改成下面這樣的,就可以使用索引了。
select * from dept shere staff_num < 1000 or dept_id > 1000;
2、使用is null 或is not null
#使用is null 或
is nuo null也會限制索引的使用,因為資料庫並沒有定義null
值。如果被索引的欄位中有很多null,就不會使用這個索引(除非索引是一個位圖索引,關於位圖索引,會在以後的blog文章裡做詳細解釋)。在sql語句中使用
select * from staff where trunc(birthdate) = '01-MAY-82';
但是把函数应用在条件上,索引是可以生效的,把上面的语句改成下面的语句,就可以通过索引进行查找。
select * from staff where birthdate < (to_date('01-MAY-82') + 0.9999);
4、比较不匹配的数据类型
比较不匹配的数据类型也是难于发现的性能问题之一。下面的例子中,dept_id
是一个varchar2
型的字段,在这个字段上有索引,但是下面的语句会执行全表扫描。
select * from dept where dept_id = 900198;
这是因为oracle
会自动把where
子句转换成to_number(dept_id)=900198
,就是3所说的情况,这样就限制了索引的使用。把SQL语句改为如下形式就可以使用索引
select * from dept where dept_id = '900198';
5、使用like子句
使用like子句查询时,数据需要把所有的记录都遍历来进行判断,索引不能发挥作用,这种情况也要尽量避免。
Like
的字符串中第一个字符如果是‘%’
则用不到索引
Column1 like ‘aaa%’ 是可以的 Column1 like ‘%aaa%’用不到
6、使用IN
尽管In
写法要比exists
简单一些,exists
一般来说性能要比In要高的多
用In
还是用Exists
的时机
当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’
一天的数据.下面的方法用不到索引
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 byGroup byDistinctIn
有时候也会用到排序
确实要排序的时候也尽量要排序小数据量,尽量让排序在内存中执行,有文章说,内存排序的速度是硬盘排序的1万倍。
在排序的字段上创建索引,让排序在内存中执行,加快排序速度。
8、在基于CBO的优化器(花费)下,表的统计数据过期。也可能导致不使用索引。
解决:执行表分析。获取表的最新信息。
9、获取的数据量过大,全部扫描效率更高
10、索引字段的值分散率太低,值太集中,如类型字段都是1,2, 状态类型Y-有效/N-无效。这类型的字段最好别建索引。
尽管在这些字段上建立了索引,但对全表数据区分度不大。最后还是会全表扫描。
推荐教程:《Oracle教程》
以上是oracle有哪些索引的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Oracle 打不開的解決辦法包括:1. 啟動數據庫服務;2. 啟動監聽器;3. 檢查端口衝突;4. 正確設置環境變量;5. 確保防火牆或防病毒軟件未阻止連接;6. 檢查服務器是否已關閉;7. 使用 RMAN 恢復損壞的文件;8. 檢查 TNS 服務名稱是否正確;9. 檢查網絡連接;10. 重新安裝 Oracle 軟件。

解決 Oracle 游標關閉問題的方法包括:使用 CLOSE 語句顯式關閉游標。在 FOR UPDATE 子句中聲明游標,使其在作用域結束後自動關閉。在 USING 子句中聲明游標,使其在關聯的 PL/SQL 變量關閉時自動關閉。使用異常處理確保在任何異常情況下關閉游標。使用連接池自動關閉游標。禁用自動提交,延遲游標關閉。

Oracle 中,FOR LOOP 循環可動態創建游標, 步驟為:1. 定義游標類型;2. 創建循環;3. 動態創建游標;4. 執行游標;5. 關閉游標。示例:可循環創建游標,顯示前 10 名員工姓名和工資。

Oracle 數據庫分頁利用 ROWNUM 偽列或 FETCH 語句實現:ROWNUM 偽列用於通過行號過濾結果,適用於復雜查詢。 FETCH 語句用於獲取指定數量的第一行,適用於簡單查詢。

要停止 Oracle 數據庫,請執行以下步驟:1. 連接到數據庫;2. 優雅關機數據庫(shutdown immediate);3. 完全關機數據庫(shutdown abort)。

在CentOS系統上搭建Hadoop分佈式文件系統(HDFS)需要多個步驟,本文提供一個簡要的配置指南。一、前期準備安裝JDK:在所有節點上安裝JavaDevelopmentKit(JDK),版本需與Hadoop兼容。可從Oracle官網下載安裝包。環境變量配置:編輯/etc/profile文件,設置Java和Hadoop的環境變量,使系統能夠找到JDK和Hadoop的安裝路徑。二、安全配置:SSH免密登錄生成SSH密鑰:在每個節點上使用ssh-keygen命令

可以通過使用 Oracle 的動態 SQL 來根據運行時輸入創建和執行 SQL 語句。步驟包括:準備一個空字符串變量來存儲動態生成的 SQL 語句。使用 EXECUTE IMMEDIATE 或 PREPARE 語句編譯和執行動態 SQL 語句。使用 bind 變量傳遞用戶輸入或其他動態值給動態 SQL。使用 EXECUTE IMMEDIATE 或 EXECUTE 執行動態 SQL 語句。

Oracle 亂碼問題可以通過以下步驟解決:檢查數據庫字符集以確保與數據相匹配。設置客戶端字符集以與數據庫相匹配。轉換數據或修改列字符集以匹配數據庫字符集。使用 Unicode 字符集,並避免多字節字符集。檢查數據庫和客戶端的語言設置是否正確。
