索引失效的情況有哪些

雖然你這列上建了索引,查詢條件也是索引列,但最終執(zhí)行計(jì)劃沒有走它的索引。下面是引起這種問題的幾個(gè)關(guān)鍵點(diǎn)。

列與列對(duì)比

某個(gè)表中,有兩列(id和c_id)都建了單獨(dú)索引,下面這種查詢條件不會(huì)走索引

select * from test where id=c_id;

這種情況會(huì)被認(rèn)為還不如走全表掃描。

存在NULL值條件

我們?cè)谠O(shè)計(jì)數(shù)據(jù)庫表時(shí),應(yīng)該盡力避免NULL值出現(xiàn),如果非要不可避免的要出現(xiàn)NULL值,也要給一個(gè)DEFAULT值,數(shù)值型可以給0、-1之類的, 字符串有時(shí)候給空串有問題,就給一個(gè)空格或其他。如果索引列是可空的,是不會(huì)給其建索引的,索引值是少于表的count(*)值的,所以這種情況下,執(zhí)行計(jì)劃自然就去掃描全表了。

select * from test where id is not null;

NOT條件

我們知道建立索引時(shí),給每一個(gè)索引列建立一個(gè)條目,如果查詢條件為等值或范圍查詢時(shí),索引可以根據(jù)查詢條件去找對(duì)應(yīng)的條目。反過來當(dāng)查詢條件為非時(shí),索引定位就困難了,執(zhí)行計(jì)劃此時(shí)可能更傾向于全表掃描,這類的查詢條件有:<>、NOT、in、not exists

select * from test where id<>500;

select * from test where id in (1,2,3,4,5);

select * from test where not in (6,7,8,9,0);

select * from test where not exists (select 1 from test_02 where test_02.id=test.id);

LIKE通配符

當(dāng)使用模糊搜索時(shí),盡量采用后置的通配符,例如:name||’%’,因?yàn)樽咚饕龝r(shí),其會(huì)從前去匹配索引列,這時(shí)候是可以找到的,如果采用前匹配,那么查索引就會(huì)很麻煩,比如查詢所有姓張的人,就可以去搜索’張%’。相反如果你查詢所有叫‘明’的人,那么只能是%明。這時(shí)候索引如何定位呢?前匹配的情況下,執(zhí)行計(jì)劃會(huì)更傾向于選擇全表掃描。后匹配可以走INDEX RANGE SCAN。

所以業(yè)務(wù)設(shè)計(jì)的時(shí)候,盡量考慮到模糊搜索的問題,要更多的使用后置通配符。

select * from test where name like 張||'%';

條件上包括函數(shù)

查詢條件上盡量不要對(duì)索引列使用函數(shù),比如下面這個(gè)SQL

select * from test where upper(name)='SUNYANG';

這樣是不會(huì)走索引的,因?yàn)樗饕诮r(shí)會(huì)和計(jì)算后可能不同,無法定位到索引。但如果查詢條件不是對(duì)索引列進(jìn)行計(jì)算,那么依然可以走索引。比如

select * from test where name=upper('sunyang');

--INDEX RANGE SCAN

這樣的函數(shù)還有:to_char、to_date、to_number、trunc等

復(fù)合索引前導(dǎo)列區(qū)分大

當(dāng)復(fù)合索引前導(dǎo)列區(qū)分小的時(shí)候,我們有INDEX SKIP SCAN,當(dāng)前導(dǎo)列區(qū)分度大,且查后導(dǎo)列的時(shí)候,前導(dǎo)列的分裂會(huì)非常耗資源,執(zhí)行計(jì)劃想,還不如全表掃描來的快,然后就索引失效了。

select * from test where owner='sunyang';

數(shù)據(jù)類型的轉(zhuǎn)換

當(dāng)查詢條件存在隱式轉(zhuǎn)換時(shí),索引會(huì)失效。比如在數(shù)據(jù)庫里id存的number類型,但是在查詢時(shí),卻用了下面的形式:

select * from sunyang where id='123';

Connect By Level

使用connect by level時(shí),不會(huì)走索引。

謂詞運(yùn)算

我們?cè)谏厦嬲f,不能對(duì)索引列進(jìn)行函數(shù)運(yùn)算,這也包括加減乘除的謂詞運(yùn)算,這也會(huì)使索引失效。建立一個(gè)sunyang表,索引為id,看這個(gè)SQL:

select * from sunyang where id/2=:type_id;

這里很明顯對(duì)索引列id進(jìn)行了’/2’除二運(yùn)算,這時(shí)候就會(huì)索引失效,這種情況應(yīng)該改寫為:

select * from sunyang where id=:type_id*2;

就可以使用索引了。

---------------------

作者:番茄發(fā)燒了

來源:CSDN

原文:https://blog.csdn.net/bless2015/article/details/84134361

版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請(qǐng)附上博文鏈接!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • ORACLE自學(xué)教程 --create tabletestone ( id number, --序號(hào)usernam...
    落葉寂聊閱讀 1,232評(píng)論 0 0
  • MYSQL 基礎(chǔ)知識(shí) 1 MySQL數(shù)據(jù)庫概要 2 簡單MySQL環(huán)境 3 數(shù)據(jù)的存儲(chǔ)和獲取 4 MySQL基本操...
    Kingtester閱讀 8,050評(píng)論 5 115
  • 第一天 7月13日OCP筆記: Oracle Ocp11g準(zhǔn)備資料: OracleFundmentals 書 管理...
    fjxCode閱讀 2,879評(píng)論 0 4
  • 企業(yè)名稱: 金柳工藝品有限公司 組別:第373期 利他1組 【日精進(jìn)打卡第 208天】 經(jīng)典名句 善因種善果 【...
    花半里_5ab7閱讀 156評(píng)論 0 0
  • 昨天有個(gè)喜訊,祁老師終于答應(yīng)假期帶你閱讀和寫作了。 祁老師身份之一,她是你們學(xué)校最優(yōu)秀的教師之一,尤其是她的作文輔...
    Grit888閱讀 484評(píng)論 0 4

友情鏈接更多精彩內(nèi)容