本篇blog講解的內容主要包括:
索引的使用。
執行計劃分析。
sql優化常見案例分析。
##索引
一,什么是索引
索引的作用只有一個,提高查找效率。
如下面sql語句:
select name from person where age = 16;
在正常情況下,MySql是從條數依次遍歷,直到讀完整個表才能得到所有age等于16的數據。
如果對age字段建立索引,MySql會維護一個索引表,索引表中存儲不同age與數據對對應關系,當查找age等于16的數據時會先在索引表中找到age等于16對應的數據id,然后直接根據數據id從數據表中需要的數據。這就類似于新華字典中的拼音查字法,先從拼音序列中找出這個字在哪一頁,然后直接去那一頁去找,避免翻遍整個字典,很大的提供了查找效率。
二,索引的利弊分析
上面說到創建索引會很大的提高查找效率,但索引也有弊端。
創建索引系統會自動維護一個索引表,每當數據增加,更新,刪除時都需要更改索引表,所以創建索引會降低增加,更新,刪除的效率。
三,創建索引的原則
創建索引針對的對象是字段,所以我們要找出適合創建索引的字段。
建議創建索引的列:
定義主鍵的數據列一定要建立索引。
定義有外鍵的數據列一定要建立索引。
對于經常查詢的數據列建立索引。
對于需要在指定范圍內的快速或頻繁查詢的數據列創建索引;
經常用在WHERE句中的數據列創建索引。
經常出現在關鍵字order by、group by、distinct后面的字段,建立索引。如果建立的是復合索引,索引的字段順序要和這些關鍵字后面的字段順序一致,否則索引不會被使用。
不建議創建索引的列:
對于那些查詢中很少涉及的列,重復值比較多的列不要建立索引。
對于定義為text、image和bit的數據類型的列不要建立索引。
對于經常存取的列避免建立索引?
限制表上的索引數目。對一個存在大量更新操作的表,所建索引的數目一般不要超過3個,多不要超過5個。索引雖說提高了訪問速度,但太多索引會影響數據的更新操作。
對復合索引,按照字段在查詢條件中出現的頻度建立索引。在復合索引中,記錄首先按照個字段排序。對于在個字段上取值相同的記錄,系統再按照第二個字段的取值排序,以此類推。因此只有復合索引的個字段出現在查詢條件中,該索引才可能被使用,因此將應用頻度高的字段,放置在復合索引的前面,會使系統可能地使用此索引,發揮索引的作用。
注:具體怎么哪些列可以創建索引,哪些列不建議創建索引,需要具體情況具體分析,需要開發中慢慢積累經驗。
四,創建索引
索引分為單索引和組合索引。但索引是給一個字段創建的索引,組合索引是給多個字段創建的索引。
比如給person表中的age字段創建索引的sql是:
navicate也支持創建索引的圖形化操作,如下:
##執行計劃
執行計劃就是分析執行某個sql語句的詳細細節。
查看某個sql語句的執行計劃很容易,只有在sql語句前添加EXPLAIN關鍵詞即可。如下:
EXPLAIN select * from person WHERE age = 16 and id > 0;
執行結果如下:
type:表示執行sql使用了哪種類型。類型的種類從好到差依次是:const、eq_reg、ref、range、indexhe和ALL。
possible_keys:可能使用到的索引。此時有兩個:PRIMARY,index_age。其中PRIMARY是主鍵,index_age是自己創建的索引。
key:實際用到的索引。
key_len:使用索引的長度,該值越小越好。
ref:
rows:數據遍歷的行數,數值越小越好。
總結:要學會且有意識的多使用執行計劃,查看每一個sql語句的執行計劃,盡量優化sql,提高項目的執行效率。
##sql優化具體分析
sql優化主要針對查詢sql進行優化,因為只有查詢語句才會出現掃描全表的情況。隨著數據量的增大,掃描全表會非常耗時,優化sql的目的是盡量掃描少的數據量。
具體細節如下:
1,盡量給字段設置默認值,避免字段值為null情況。
如果字段是int類型的age,首先給age創建索引時null不會參與創建索引。where age=0比where age is null效率高。
2,在where語句中少使用or,使用or將不使用索引。
如select name where age = 16 or age = 20
可以寫成:
select name where age = 16 union all?select name where age = 20
3,在where語句中避免使用in,
如select * from score where student_id in (select id from student where name='guoxiang')
可以寫成:
select * from score sc? where exists?(select 1 from student st? where st.name='guoxiang' and st.id = sc.student_id)
想要了解更多的java應用技術那就加入我們吧!