成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

數(shù)據(jù)庫索引優(yōu)化 oracle

KevinYan / 3020人閱讀

摘要:請(qǐng)把數(shù)據(jù)表想象成一本書,索引就是書的目錄。那么索引過多會(huì)導(dǎo)致插入更新操作性能下降。哪些查詢會(huì)無法使用索引優(yōu)化中要注意這些情況,調(diào)整以便使用索引模糊查詢?cè)谧址_端使用通配符,會(huì)忽略索引。

請(qǐng)把數(shù)據(jù)表想象成一本書, 索引就是書的目錄。
這里只討論寫ORACLE SQL中優(yōu)化時(shí)常遇到的索引,一般有以下幾類,
1. normal 順序的btree 索引,字段值可以為空,
2. unique 唯一的順序索引,也就是說書的目錄不能出現(xiàn)重復(fù)項(xiàng),這樣索引建立時(shí),字段是不允許有空值的
3. 組合索引 多個(gè)字段放到一起建立的 normal索引,類似于書的目錄是多級(jí)的
4. 函數(shù)索引
5. 位圖索引 適合于某列的取值情況較少, 例如性別,只有男女兩個(gè)值
更復(fù)雜的索引, 不作討論

索引的優(yōu)缺點(diǎn):

索引的優(yōu)點(diǎn)
檢索速度快,根據(jù)目錄去找自己需要的東西, 顯然比整個(gè)書翻一遍(全表掃描)要快很多
索引的缺點(diǎn):
1. 需要多帶帶的存儲(chǔ)空間去保存索引, 如果一張表建了很多索引, 那么索引的空間會(huì)更大
2. 如果一張表高并發(fā)操作主要是插入、更新。那么索引過多會(huì)導(dǎo)致插入更新操作性能下降。
類似書的內(nèi)容總在變,目錄自然也要同時(shí)跟著變化。維護(hù)目錄會(huì)增加額外的消耗

oracle 是如何通過索引找到記錄的?

在書目錄查找的時(shí)候, 當(dāng)我們找到需要的章節(jié)時(shí),會(huì)記住這些章節(jié)的頁碼, 再翻到相應(yīng)的頁碼去尋找我們需要的內(nèi)容。
這里有兩次查找: 1. 從目錄找頁碼 2. 根據(jù)頁碼在內(nèi)容中查找自己需要的
oracle 也是這樣, 根據(jù)索引篩選可能需要的記錄 rowid(rowid 是oracle每一行記錄的實(shí)際物理地址,類似頁碼,精確到了每一行),利用rowid 讀取行記錄, 逐行讀取記錄的時(shí)候再比較這些記錄是否符合其他where條件。最后返回符合條件的行。
注意:一次不可分割的子查詢中中, 不論表建了多少索引,只會(huì)使用一條索引。例如

select * from users where userid=3 and username like "json%"。

假設(shè)userid跟username字段都建立了索引,如果同時(shí)使用兩條索引,userid返回了等于3的一個(gè)rowid(這里是假設(shè),實(shí)際情況一般不知一個(gè),例如用戶登錄記錄表), username 返回json開頭的5個(gè)rowid。 通過兩組rowid 我們還是無法得知,哪些rowid同時(shí)符合兩個(gè)條件。

如何通過索引查找的更快

oracle 有自己的分析規(guī)則,還是上面的例子, 利用userid查找起來 更快,一方面因?yàn)樗环祷亓艘粋€(gè)rowid, 后續(xù)的查找只需遍歷一個(gè)結(jié)果集,判斷這個(gè)結(jié)果集是否 like "json%",另一方面like操作更耗時(shí)。哪條索引查出來的rowid少自然就更快。
我們可以用索引提示的方式,來指定oracle使用哪條索引,使用這樣的格式 /*+index(表名或表別名 索引名)*/

select /*+index(users users_idx1)*/ * from users where userid=3 and username like "json%"

實(shí)際情況中, 可能更復(fù)雜,例如:

select * from users where userid=3 and login_time=to_date("yyyy-mm-dd hh24:mi:ss", "2014-02-14 03:00:00")

這里可能userid 跟 login_time 都是獨(dú)立的normal索引,而且查詢效率都較高,需要根據(jù)表的實(shí)際情況去選擇。如果 用戶量很大,查詢的時(shí)間只是到天,可能使用userid字段的索引更快,如果查詢的時(shí)間精確到了秒, 可能時(shí)間索引更快

如果需要查看 oracle 使用了哪條索引,查看執(zhí)行計(jì)劃便可,在pl/sql工具中,只需按F5或explain sql

組合索引的情況復(fù)雜一些

類似書的目錄有多級(jí)目錄一樣, 組合索引是建立在多個(gè)字段的, 不同的字段順序不同的組合索引,類似多級(jí)目錄,調(diào)換了上下級(jí),就是新的目錄。
基本上書籍都是多級(jí)目錄, 一般從我們一級(jí)目錄開始查找。
組合索引也遵循這樣的規(guī)則,示例如下:

create index user_idx1 on user_log(userid, username, log_time)
// 以下方式,查詢條件中使用了組合索引第一列(前導(dǎo)列)都可以使用 組合索引
select * from user_log where userid=3 and  username like "json%" and log_time=to_date("yyyy-mm-dd hh24", "2014-02-14 03");
select * from user_log where userid=3 and log_time=to_date("yyyy-mm-dd hh24", "2014-02-14 03");
select * from user_log where userid=3;
// 跳過 第一列的情況, 將不再使用使用組合索引(oracle 9i以上版本會(huì)使用跳躍掃描)
selec * from user_log where log_time=to_date("yyyy-mm-dd hh24", "2014-02-14 03");
函數(shù)索引

查找中對(duì)字段使用函數(shù)時(shí),將會(huì)忽略直接創(chuàng)建于字段上的索引。

select * from users where upper(username) = "JSON"

這樣的查詢, 需要?jiǎng)?chuàng)建函數(shù)索引

create index users_upper_idx on users(upper(username))

理解起來也很簡(jiǎn)單, 當(dāng)對(duì)字段使用了函數(shù)的時(shí)候,查詢已經(jīng)不是字段的值了,原來基于字段值建立的索引,自然失效。

哪些查詢會(huì)無法使用索引

sql優(yōu)化中要注意這些情況,調(diào)整sql以便使用索引
模糊查詢?cè)谧址_端使用通配符,會(huì)忽略索引。如 like "%json"like "%json%"
對(duì)非函數(shù)索引的字段, 使用了函數(shù)
對(duì)于index索引 不會(huì)存儲(chǔ) null類型,is null 是不會(huì)使用該類索引的
索引本身是利用合理的數(shù)據(jù)結(jié)構(gòu),根據(jù)值的比較,來達(dá)到快速檢索的目的,以上列舉的幾種情況,顯然都無法通過比較值來查找到最終結(jié)果

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/17431.html

相關(guān)文章

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<