案例:
(1)首先建立乙個article表:
往其中插入三條資料:
(2)查詢category_id為1且comments大於1的情況下,views最多的article_id
select id,author_id from article where category_id=
1and comments>
1order
by views desc
limit
1;
使用explain語句來分析這條sql語句寫得好不好
explain
select id,author_id from article where category_id=
1and comments>
1order
by views desc
limit
1;
結果如下:
type為all:說明是全表掃瞄,不好
extra顯示using filesort:說明mysql中無法用索引來排序,所以mysql會用外部排序——即檔案內排序來排序資料並返回查詢結果,這樣子也不好
(3)我們來查詢一下article表的索引(其實是沒有的,因為建表時只是將id設為了主鍵,沒有建立除主鍵索引以外的索引)
show
index
from article;
由圖可見,索引是主鍵索引,下面開始優化
優化:
(1)新建索引,發現該索引不合適,刪除該索引
由於上述查詢語句中用到了category_id,comments,views欄位作為查詢條件,所以嘗試將索引應該建在這三個條件上面
create
index idx_article_ccv on article(category_id,comments,views)
;
建好索引後再查詢一下全部索引:
現在再來分析一下查詢語句的效能
explain
select id,author_id from article where category_id=
1and comments>
1order
by views desc
limit
1;
發現type欄位下的all變成了range,用到了idx_article_ccv索引,但是using filesort還有。
如果sql語句中comments>1條件改為了comments=3,那麼效能分析會呈現以下情況:
可以看到,using filesort沒有了,type欄位下的range變成了ref。
這就是範圍查詢帶來的索引失效問題,因為按照btree索引的工作原理,先排序category_id,若遇到相同category_id再排序comments,若遇到相同的comments再排序views,當comments欄位在聯合索引裡處於中間位置時,comments>1條件是乙個範圍值(range),mysql無法利用索引再對後面的views部分進行檢索,即range型別查詢字段後面的索引失效。這個問題會在本文後面得到解決。
現在刪除idx_article_ccv索引,重新建立新的索引
(2)重建索引
繞過comments欄位,在categroy_id和views欄位上建索引:
create
index idx_article_cv on article(category_id,views)
;
再次使用explain來分析該查詢語句的效能
explain
select id,author_id from article where category_id=
1and comments>
1order
by views desc
limit
1;
由圖可見,使用了這個索引已經將該sql語句優化到最佳效果!
案例
(1)建立乙個class表和乙個book表
class表(id為主鍵自增):
book表(bookid為主鍵自增):
(2)使用explain語句進行效能分析
explain
select
*from class left
join book on class.card=book.card;
此時,type為all,顯然需要優化
(3)對右表book表新增索引
create
index idx_book_card on book(card)
;
再用explain語句分析(2)中的查詢語句,結果如下:
由此可見,效能有明顯的提公升
現在刪去索引idx_book_card
(4)對左表class表新增索引
create
index idx_class_card on class(card)
;
再用explain語句分析(2)中的查詢語句,結果如下:
與(3)中的結果對比可見,將索引建立在右表上效能好。
(5)結論
通過分析可得出結論,如果sql語句是left join,則在右表建立索引;如果sql語句是right join,則在左表建立索引
(1)再建立乙個phone表(phoneid為主鍵自增),並把這三個表中的索引全部刪去
(2)來用explain語句分析以下語句
explain
select
*from class left
join book on class.card=book.card left
join phone on book.card=phone.card;
(3)在book表和phone表上的card欄位建索引
create
index idx_book_card on book(card)
;create
index idx_phone_card on phone(card)
;
繼續用explain語句分析(2)中的sql語句:
從type屬性和rows屬性以及extra屬性中看到,建立索引後效率提公升了很多
(4)結論:
盡可能減少join語句中的nested loop的迴圈總次數,「永遠用小結果集驅動大的結果集;
優化要先優化nested loop的內層迴圈;
保證join語句中被驅動表上join條件字段已經被索引;
當無法保證被驅動表的join條件欄位被索引且記憶體資源充足的前提下,不要太吝嗇joinbuffer的設定
MYSQL優化 索引(一)
對於mysql的優化的各種方式中,索引方式佔很大比例。當資料很大時,才會感受到索引的魅力。為了方便學習和工作中使用,收集實驗整理下的。我們知道,查詢資料時,先把資料從磁碟塊中讀取到記憶體中,再做處理的。如果沒有索引時,就會容易全表查詢。而io操作又是最耗時的。比如 1 100放入磁碟快1中,101 ...
mysql 優化 聚集索引 mysql 索引優化
一.聚集索引 clustered index innodb預設依據主鍵列聚集,myisam不使用 特點 b樹每個葉子包含實際資料行,資料按照索引順序地儲存在物理頁上。優點 1.範圍查詢,獲取指定id的全部資料只需從磁碟讀取少量資料頁 如果不使用聚集索引,每條資料可能引起一次磁碟io。2.由於索引和資...
mysql索引優化原則 MySQL 索引優化原則
索引優化原則 1 最左字首匹配原則,聯合索引,mysql會從做向右匹配直到遇到範圍查詢 3 and d 4 如果建立 a,b,c,d 順序的索引,d是用不到索引的,如果建立 a,b,d,c 的索引則都可以用到,a,b,d的順序可以任意調整。2 和in可以亂序,比如a 1 and b 2 and c ...