摘要:請把數據表想象成一本書,索引就是書的目錄。那么索引過多會導致插入更新操作性能下降。哪些查詢會無法使用索引優化中要注意這些情況,調整以便使用索引模糊查詢在字符串開端使用通配符,會忽略索引。
請把數據表想象成一本書, 索引就是書的目錄。
這里只討論寫ORACLE SQL中優化時常遇到的索引,一般有以下幾類,
1. normal 順序的btree 索引,字段值可以為空,
2. unique 唯一的順序索引,也就是說書的目錄不能出現重復項,這樣索引建立時,字段是不允許有空值的
3. 組合索引 多個字段放到一起建立的 normal索引,類似于書的目錄是多級的
4. 函數索引
5. 位圖索引 適合于某列的取值情況較少, 例如性別,只有男女兩個值
更復雜的索引, 不作討論
索引的優點
檢索速度快,根據目錄去找自己需要的東西, 顯然比整個書翻一遍(全表掃描)要快很多
索引的缺點:
1. 需要多帶帶的存儲空間去保存索引, 如果一張表建了很多索引, 那么索引的空間會更大
2. 如果一張表高并發操作主要是插入、更新。那么索引過多會導致插入更新操作性能下降。
類似書的內容總在變,目錄自然也要同時跟著變化。維護目錄會增加額外的消耗
在書目錄查找的時候, 當我們找到需要的章節時,會記住這些章節的頁碼, 再翻到相應的頁碼去尋找我們需要的內容。
這里有兩次查找: 1. 從目錄找頁碼 2. 根據頁碼在內容中查找自己需要的
oracle 也是這樣, 根據索引篩選可能需要的記錄 rowid(rowid 是oracle每一行記錄的實際物理地址,類似頁碼,精確到了每一行),利用rowid 讀取行記錄, 逐行讀取記錄的時候再比較這些記錄是否符合其他where條件。最后返回符合條件的行。
注意:一次不可分割的子查詢中中, 不論表建了多少索引,只會使用一條索引。例如
select * from users where userid=3 and username like "json%"。
假設userid跟username字段都建立了索引,如果同時使用兩條索引,userid返回了等于3的一個rowid(這里是假設,實際情況一般不知一個,例如用戶登錄記錄表), username 返回json開頭的5個rowid。 通過兩組rowid 我們還是無法得知,哪些rowid同時符合兩個條件。
如何通過索引查找的更快oracle 有自己的分析規則,還是上面的例子, 利用userid查找起來 更快,一方面因為它只返回了一個rowid, 后續的查找只需遍歷一個結果集,判斷這個結果集是否 like "json%",另一方面like操作更耗時。哪條索引查出來的rowid少自然就更快。
我們可以用索引提示的方式,來指定oracle使用哪條索引,使用這樣的格式 /*+index(表名或表別名 索引名)*/
select /*+index(users users_idx1)*/ * from users where userid=3 and username like "json%"
實際情況中, 可能更復雜,例如:
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 都是獨立的normal索引,而且查詢效率都較高,需要根據表的實際情況去選擇。如果 用戶量很大,查詢的時間只是到天,可能使用userid字段的索引更快,如果查詢的時間精確到了秒, 可能時間索引更快
如果需要查看 oracle 使用了哪條索引,查看執行計劃便可,在pl/sql工具中,只需按F5或explain sql
組合索引的情況復雜一些類似書的目錄有多級目錄一樣, 組合索引是建立在多個字段的, 不同的字段順序不同的組合索引,類似多級目錄,調換了上下級,就是新的目錄。
基本上書籍都是多級目錄, 一般從我們一級目錄開始查找。
組合索引也遵循這樣的規則,示例如下:
create index user_idx1 on user_log(userid, username, log_time) // 以下方式,查詢條件中使用了組合索引第一列(前導列)都可以使用 組合索引 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以上版本會使用跳躍掃描) selec * from user_log where log_time=to_date("yyyy-mm-dd hh24", "2014-02-14 03");函數索引
查找中對字段使用函數時,將會忽略直接創建于字段上的索引。
select * from users where upper(username) = "JSON"
這樣的查詢, 需要創建函數索引
create index users_upper_idx on users(upper(username))
理解起來也很簡單, 當對字段使用了函數的時候,查詢已經不是字段的值了,原來基于字段值建立的索引,自然失效。
哪些查詢會無法使用索引sql優化中要注意這些情況,調整sql以便使用索引
模糊查詢在字符串開端使用通配符,會忽略索引。如 like "%json" 或 like "%json%"
對非函數索引的字段, 使用了函數
對于index索引 不會存儲 null類型,is null 是不會使用該類索引的
索引本身是利用合理的數據結構,根據值的比較,來達到快速檢索的目的,以上列舉的幾種情況,顯然都無法通過比較值來查找到最終結果
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/17431.html
閱讀 2284·2023-04-25 16:42
閱讀 1198·2021-11-22 14:45
閱讀 2330·2021-10-19 13:10
閱讀 2821·2021-09-29 09:34
閱讀 3398·2021-09-23 11:21
閱讀 2094·2021-08-12 13:25
閱讀 2176·2021-07-30 15:15
閱讀 3488·2019-08-30 15:54