1.聯(lián)合索引
對于多列索引,過濾條件要使用索引必須按照索引建立時的順序,依次滿足,一旦跳過某個字段,索引后面的字段都無法被使用。
例如以下情況,索引從左到右的順序為age,classId,name,但是在查詢時跳過了age,因此該查詢無法使用索引。
CREATE INDEX idx_age_classid_name ON student(age,classId,name);
SELECT SQL_NO_CACHE * FROM student WHERE student.classId=1 AND student.name = 'abcd';
2. 使用函數(shù)
查詢條件中使用了函數(shù)會導(dǎo)致索引失效
例如以下情況,使用了函數(shù)導(dǎo)致索引失效
SELECT SQL_NO_CACHE * FROM student WHERE LEFT(student.name,3) = 'abc';
3. 含有計算
查詢條件中含有計算會導(dǎo)致索引失效
例如以下情況:
SELECT SQL_NO_CACHE id, stuno, NAME FROM student WHERE stuno+1 = 900001;
4. 類型轉(zhuǎn)換
查詢條件兩邊類型不同,需要自動或主動的進行類型轉(zhuǎn)換,會導(dǎo)致索引失效。例如以下情況,name字段假設(shè)為字符串,但查詢條件右邊為數(shù)字123,這時會自動進行類型轉(zhuǎn)換進行比較,因此無法使用索引。
-- 假設(shè)name字段有索引且name字段類型為字符串
SELECT SQL_NO_CACHE * FROM student WHERE name=123;
5. 范圍條件右邊的列索引失效
當有聯(lián)合索引且查詢條件含有范圍比較時,比如:(<) (<=) (>) (>=) 和 between 等,索引中被比較范圍的列的右邊的不能使用。
例如下列情況,索引從左到右包含age,classId,name,但在查詢條件中classId為范圍比較,因此索引中的name列無法使用,因為在索引中name在列classId的右邊。
create index idx_age_name_classId on student(age,classId,name);
SELECT SQL_NO_CACHE * FROM student
WHERE student.age=30 AND student.classId>20 AND student.name = 'abc' ;
6. 不等于(!= 或者<>)索引失效
查詢條件中包含不等于的判斷時,索引無法使用。
例如:
CREATE INDEX idx_name ON student(NAME);
SELECT SQL_NO_CACHE * FROM student WHERE student.name != 'abc';
7. is null可以使用索引,is not null無法使用索引
在查詢條件中,IS NULL可以使用索引,而IS NOT NULL 無法使用索引。例如:
SELECT SQL_NO_CACHE * FROM student WHERE age IS NOT NULL;
8. like以通配符%開頭索引失效
在使用LIKE關(guān)鍵字進行查詢的查詢語句中,如果匹配字符串的第一個字符為’%‘,索引就不會起作用。只有’%'不在第一個位置,索引才會起作用。例如:
--可以使用索引
SELECT SQL_NO_CACHE * FROM student WHERE name LIKE 'ab%';
--無法使用索引
SELECT SQL_NO_CACHE * FROM student WHERE name LIKE '%ab%';
9. OR 前后存在非索引的列,索引失效
在WHERE子句中,如果在OR前的條件列進行了索引,而在OR后的條件列沒有進行索引,那么索引會失效。也就是說,OR前后的兩個條件中的列都是索引時,查詢中才使用索引。
因為OR的含義就是兩個只要滿足一個即可,因此只有一個條件列進行了索引是沒有意義的,只要有條件列沒有進行索引,就會進行全表掃描,因此所以的條件列也會失效。
例如以下情況,如果classId字段上沒有索引,那么該查詢語句無法使用索引。
SELECT SQL_NO_CACHE * FROM student WHERE age = 10 OR classid = 100;
10. 字符集不同
統(tǒng)一使用utf8mb4( 5.5.3版本以上支持)兼容性更好,統(tǒng)一字符集可以避免由于字符集轉(zhuǎn)換產(chǎn)生的亂碼。不同的字符集進行比較前需要進行轉(zhuǎn)換會造成索引失效。
注意:
(1)最好讓主鍵自增 ,讓存儲引擎自己為表生成主鍵,而不是我們手動插入 ,這樣在插入新的數(shù)據(jù)時不需要頁面分裂,避免性能損耗。
(2)將范圍查詢條件放置語句最后,這樣可以避免上述第五點情況。
(3)最好在設(shè)計數(shù)據(jù)庫的時候就將字段設(shè)置為 NOT NULL 約束,比如你可以將 INT 類型的字段,默認值設(shè)置為0。將字符類型的默認值設(shè)置為空字符串(‘’)。
(4)對于單列索引,盡量選擇針對當前query過濾性更好的索引。文章來源:http://www.zghlxwxcb.cn/news/detail-806758.html
(5)在選擇組合索引的時候,當前query中過濾性最好的字段在索引字段順序中,位置越靠前越好。文章來源地址http://www.zghlxwxcb.cn/news/detail-806758.html
到了這里,關(guān)于SQL筆記 -- 索引失效情況的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!