在mysql5.7中,一般為了查詢速度,通常會引入索引,但是有時候我們的索引並沒有引起效果,所以整理下一般在什麼情況下會引起索引失效,即索引沒有被使用。
現在我們有乙個名為t_test的資料表,他的字段與資料儲存型別如下所示,並且在字段phone欄位建立索引:
名稱型別
長度id
bigint
0name
varchar
10phone
varchar
20age
int0
adreess
varchar50
我們查詢phone欄位為具體數值的查詢,可以為:
select * from t_test where phone =13555455506
可以正常得到我們想要的結果,但是由於phone為varchar字元型別,而不是長整型,所以我們檢視下這個sql的執行計畫:
explain select * from t_test where phone =13555455506
並且可以得到以下計畫:
idselect_type
table
partitions
type
possible_keys
keykey_length
refrows
filtered
extra
1******
t_test
allindex_phone
1100
using where
我們可以通過上述列表看到possible_keys為執行時預計可能用到的索引為phone上的索引,key為實際用到的索引為空,則表示實際查詢不會用到索引,則是因為mysql會將我們傳入的引數隱式轉換為資料表中儲存的型別,索引時根據btree的有序性進行遍歷的,但是轉換之後的引數破環了有序性的規則。
所以我們要將傳入引數加上引號,以表示此引數為字串型別,如下:
select * from t_test where phone ='13555455506'
還是使用上面的表,我們在age欄位上加入索引,現在我們有乙個查詢,要求查詢年齡age在兩年前為18的資料,則查詢語句如下:
select * from t_test where age -2=18
可以正常得到我們想要的結果,但是由於我們在age查詢的時候給他賦予了表示式,所以我們檢視下這個sql的執行計畫:
explain select * from t_test where age -2=18
並且可以得到以下計畫:
idselect_type
table
partitions
type
possible_keys
keykey_length
refrows
filtered
extra
1******
t_test
all1
100using where
我們可以清楚看到,索引並沒有使用,那麼我們應該如何修改以達到要求呢,我們只需要把計算挪到等號右側即可:
select * from t_test where age =18+2
原因與第乙個類似。資料庫在計算時無法保證與索引樹一致,只好不用索引。
現在我們有這樣乙個查詢,查詢出手機號碼前三位為158的資料,則查詢語句如下:
select * from t_test where left(phone,3)='158'
可以正常得到我們想要的結果,但是由於我們使用了函式,所以我們檢視下這個sql的執行計畫,語句省略,直接看結果:
idselect_type
table
partitions
type
possible_keys
keykey_length
refrows
filtered
extra
1******
t_test
all1
100using where
我們可以修改為如下語句:
select * from t_test where phone like '158%'
原因同上面兩個類似,這正是用到了我們msyql的索引最左原則進行匹配。
select * from t_test where adreess like '%天安門%'
可以正常得到我們想要的結果,但是由於我們使用了左右模糊匹配,則可以檢視sql的執行計畫如下,檢視結果:
idselect_type
table
partitions
type
possible_keys
keykey_length
refrows
filtered
extra
1******
t_test
all1
100using where
這裡面也是由於不符合最左字首匹配原則。如果我們只查詢主鍵id與該索引字段,仍可使用索引,查詢如下:
select id,adreess from t_test where adreess like '%天安門%'
由於不符合最左字首,即使使用索引樹,查詢只能跟隨btree數依次遍歷。
聯合索引我們要依據最左字首原則,即最左欄位,最左資料
如果我們刪除age與phone上的單列索引,新增(age,phone)聯合索引,則有以下規律
select * from t_test where age =20 //使用了該聯合索引
select * from t_test where phone like '131%' //沒有使用該聯合索引
select * from t_test where age =20 and phone like '131%'//使用了該聯合索引
mysql索引失效 常見mysql索引失效條件
使用索引的一般語句 1 where條件中有or,除非or的所有欄位都有索引,只要有乙個沒有索引,就不走索引 explain select from jf user ju where ju.user id or ju.superior1 yyy user id是主鍵,superior1是普通索引,結果...
mysql 主鍵失效 MySQL索引(索引失效)
索引 索引也是一張表,該錶儲存了主鍵與索引字段,並指向實體表的記錄。myisam儲存引擎,資料檔案 索引檔案 表結構檔案分開儲存 innodb儲存引擎,資料和索引儲存在乙個檔案中 b tree索引 hash索引 hash索引 只有memory儲存引擎支援 查詢一條記錄的速度非常快 b tree索引 ...
mysql 索引失效場景 Mysql 索引失效場景
例如 一張user表 有欄位屬性 name,age 其中name為索引 下面列舉幾個索引失效的情況 1.select from user where name xzz or age 16 例如這種情況 當語句中帶有or的時候 即使有索引也會失效。2.select from user where na...