1.常規索引優化方式
1.1.單表優化
# 查詢category_id為1且comments大於1的情況下,views最多的article id SELECT id, author_id FROM article WHERE category_id = 1 AND comments > 1 ORDER BY views DESC LIMIT 1; EXPLAIN SELECT id, author_id FROM article WHERE category_id = 1 AND comments > 1 ORDER BY views DESC LIMIT 1; # 單表優化--建立對應索引 優化方案:cv建立索引 create index idx_article_cv on article(category_id,views);
總結:mysql索引是遵從B樹索引原則,當建立ccv索引時,先排序category_id,如果遇到相同的category_id則再排序comments,如果遇到相同的comments則再排序
views。而如果處於聯合索引中間位置的字段comments > 1是一個范圍值(range),則無法利用索引再對后面的views部分進行檢索,即range類型查詢字段后面的
索引會失效。
這種情況建立cv索引最好。
1.2.兩表優化
EXPLAIN SELECT b.bookid,c.card FROM book b LEFT JOIN class c ON b.card = c.card; # 優化方案:兩表連接,左連接索引建立在右表,右連接索引建立在左表;或者查詢對調位置 create index idx_class_card on class(card);
總結:兩表連接,左連接索引建立在右表,右連接索引建立在左表;或者查詢對調位置。
且注意小表驅動大表。
1.3.三表優化
# 針對連接的第三張表phone再在右表phone上建立一個索引 create index idx_class_card on class(card); create index idx_phone_card on phone(card); EXPLAIN SELECT * FROM class LEFT JOIN book ON class.card = book.card LEFT JOIN phone ON book.card = phone.card;
總結:三表連接,左連接索引建立在右表連接字段上,右連接建立在左表連接字段上;且注意小表驅動大表;如上,LEFT JOIN都建立在右表連接字段上。
三表連接,建立了兩個表的索引。
2.索引失效
2.1.索引失效七字訣
模:模糊查詢,like 如果以%開頭,索引會失效;
型:數據類型,如果數據類型錯誤了,索引會失效;
數:函數,對索引字段使用內部函數,索引會失效,應該建立基於函數的索引;
空:null,索引不存儲空值,如果不限制索引列是not null,數據庫會認為索引列可能存在空值,也不會按照索引進行計算;
運:運算,對索引列進行加減乘除等運算會導致索引失效;
最:最左原則的意思,在復合索引中,索引列的順序非常重要,如果不是按照索引列最左列開始進行查找,則無法使用索引;
快:全表掃描更快的意思,如果數據庫預計使用全表掃描比使用索引更快,那就不會使用索引
2.2.硅谷十句訣
硅谷十句訣:
1.全值匹配我最愛:建立的索引個數和順序與查詢的字段個數和順序完全一致。
2.最佳左前綴法則:如果索引包含多列(復合索引),需要遵守最左前綴法則,指的是查詢從索引最左前列開始並且不跳過索引中的列。
所謂:“帶頭大哥不能死,中間兄弟不能斷”
3.不要在索引列上做任何操作(計算、函數、(自動or手動)類型轉換),會導致索引失效而轉向全表掃描
4.存儲引擎不能使用索引中范圍條件右邊的列,即范圍之后全失效
5.盡量使用覆蓋索引(只訪問索引的查詢(索引列和查詢列一致)),減少select*
6.mysql在使用不等於(!=或者<>)的時候無法使用索引會導致全表掃描
7.is null ,is not null 也無法使用索引
8.like以通配符開頭('%ab...)mysq|索引失效會變成全表掃描的操作
可以使用覆蓋索引解決like %char% 不走索引的問題
9.字符串不加單引號會導致索引失效
10.少用or.用它來連接時令索引失效
小總結(判斷索引是否被使用):