1.情景展示
我們知道:無論是mysql還是oracle,只要使用like查詢,就可能會面臨索引失效(不走索引)的問題;
下面,我們將一起來看看什么情況下,索引會失效,以及如何解決不走索引的問題。
已知,base_org_info表有兩個索引
我們需要使用ORGNAME進行模糊查詢,據此進行案例展示。
2.具體分析
要想解決走不走索引的問題,首先,我們需要確定的是:索引在哪的問題?
通常情況下,我們為了提高查詢效率,往往會建一些索引;
我們要使用索引,需要滿足兩個條件:
第一,創建索引;
第二,將要查詢條件(where)包含索引列。
舉個例子:
如果沒有where限制條件,查詢的將是所有數據,這一點大家都知道。
只要查詢條件包含索引列,就會走索引;
即使,存在其他限制條件,也會走索引;
但是,like查詢可能會讓索引失效,具體見下文。
另外的話,主鍵字段本身索引,而且是唯一索引。
情形一:like '字符串%'和like '字符串_';
這種情況和'='一樣,都會走索引。
情形二:like '%字符串'和like '_字符串';
不走索引,索引IDX_BASE_ORG_INFO_ORGNAME失效;
情形三:like '%字符串%'和like '_字符串_';
不走索引,索引IDX_BASE_ORG_INFO_ORGNAME失效;
說明:_和%的索引失效情況,一模一樣,不再截圖展示。
3.解決方案
先來說說這種情況:
雖然,限制條件orgseq是索引列,但是,這個索引不起作用,因為like查詢走的是全表掃描!!!
解決方案一:創建復合索引;
為where后面的所有限制條件,聯合創建一個索引。
一起來看下效果:
此時,咱們新建的聯合索引生效了,是不是到此為止了?
別急,一個神奇的事情將會發生:
我們可以看到:索引,又失效了!
所以說,這種方式僅限於查詢對應的索引列,一旦查詢的字段不是組合索引當中的索引列的話,索引將會失效;
另外,這種方式也僅限於:少量的查詢限制條件,如果字段太多就失去了使用索引的意義。
解決方案二:使用內連接。(推薦使用)
SELECT
t.ORGSEQ,
t2.ORGNAME
FROM
base_org_info_copy1 t,
( SELECT t.ORGID, t.ORGNAME FROM base_org_info_copy1 t WHERE t.ORGNAME LIKE '%陽_' ) t2
WHERE
t2.ORGID = t.ORGID
第一步:為要使用like '%字符串%'或者'%字符串'的列創建單獨索引;
第二步:查詢該字段與主鍵列,並將查詢結果作為一張表;
第三步:與原來的表,使用主鍵列建立內連接;
第四步:其它查詢限制條件使用原來的表進行限制。
我們可以從上圖當中看到,走了索引列:IDX_BASE_ORG_INFO_ORGNAME;
用了唯一索引:主鍵列ORGID,因為兩表關聯用的它。
4.擴展
b+
樹,組合索引會形成多字段順序排序,比如下圖,會先按照姓名進行排序,姓名相等就再按照年齡排序,所以會有組合索引的最左前綴原理(這就是使用組合索引,並且只查詢索引列的時候,like'%字符串'可以走組合索引的原因);
like
查詢姓名,例如
like "張%"
,則也可以使用最左前綴原理,先索引到
張六
,然后遍歷查詢,直到姓名不以
張
開頭。
