Mysql索引優化 (查閱整理)

一、什麼是索引?

  索引用來快速地尋找那些具有特定值的記錄,所有MySQL索引都以B-樹的形 式保存。如果表有1000個記錄,通過索引查找記錄 至少要比順序掃描記錄快100倍。如果不加索引的話,那麼查找任何哪怕只是一條特定的數據都會進行一次全表掃描,如果一張表的數據量很大而符合條件的結果又很少,那麼不加索引會引起致命的 性能下降。但是也不是什麼情況都非得建索引不可,比如性別可能就只有兩個值,建索引不僅沒什麼優勢,還會影響到更新速度,這被稱爲過度索引。

 

二、複合索引

 

        兩個或更多個列上的索引被稱作複合索引。
利 用索引中的附加列,您可以縮小搜索的範圍,但使用一個具有兩列的索引不同於使用兩個單獨的索引。複合索引的結構與電話簿類似,人名由姓和名構成,電話簿首 先按姓氏對進行排序,然後按名字對有相同姓氏的人進行排序。如果您知道姓,電話簿將非常有用;如果您知道姓和名,電話簿則更爲有用,但如果您只知道名不 姓,電話簿將沒有用處。所以說創建複合索引時,應該仔細考慮列的順序。對索引中的所有列執行搜索或僅對前幾列執行搜索時,複合索引非常有用;僅對後面的任意列執行搜索時,複合索引則沒有用處。

 

索引不包括含有NULL的值

 

        使用 is null 或is nuo null也會限制索引的使用,因爲數據庫並沒有定義null值。如果被索引的列中有很多null,就不會使用這個索引(除非索引是一個位圖索引,關於位圖 索引,會在以後的blog文章裏做詳細解釋)。在sql語句中使用null會造成很多麻煩。
解決這個問題的辦法就是:建表時把需要索引的列定義爲非空(not null)


四 、 使用短索引


        對串列進行索引,如果可能應該指定一個前綴長度。例如,如果有一個CHAR(255)的 列,如果在前10 個或20 個字符內,多數值是惟一的,那麼就不要對整個列進行索引。短索引不僅可以提高查詢速度而且可以節省磁盤空間和I/O操作。

 

五、排序的索引問題


mysql查詢只使用一個索引,因此如果where子句中已經使用了索引的話,那麼order by中的列是不會使用索引的。因此數據庫默認排序可以符合要求的情況下不要使用排序操作;儘量不要包含多個列的排序,如果需要最好給這些列創建複合索引。

 

六、like語句操作


一般情況下不鼓勵使用like操作,如果非使用不可,如何使用也是一個問題。like “%aaa%” 不會使用索引而like “aaa%”可以使用索引。

 

七、不要在列上進行運算


 

如果沒有使用基於函數的索引,那麼where子句中對存在索引的列使用函數時,會使優化器忽略掉這些索引。下面的查詢就不會使用索引:

但是把函數應用在條件上,索引是可以生效的,把上面的語句改成下面的語句,就可以通過索引進行查找。

八、不使用NOT IN和<>操作

 

NOT IN和<>操作都不會使用索引將進行全表掃描。 NOT IN可以NOT EXISTS代替,id<>3則可使用id>3 or id<3來代替。

如以下語句:

可以用:

代替。

 

九、比較不匹配的數據類型

 

比較不匹配的數據類型也是難於發現的性能問題之一。
下面的例子中,dept_id是一個varchar2型的字段,在這個字段上有索引,但是下面的語句會執行全表掃描:

select * from dept where dept_id = 900198;


這是因爲oracle會自動把where子句轉換成to_number(dept_id)=900198,就是3所說的情況,這樣就限制了索引的使用。
把SQL語句改爲如下形式就可以使用索引

 

十、索引的缺點

  到目前爲止,我們討論的都是索引的優點。事實上,索引也是有缺點的。

  首先,索引要佔用磁盤空間。通常情況下,這個問題不是很突出。但是,如果你創建每一種可能列組合的索引,索引文件體積的增長速度將遠遠超過數據文件。如果你有一個很大的表,索引文件的大小可能達到操作系統允許的最大文件限制。

  第二,對於需要寫入數據的操作,比如DELETE、UPDATE以及INSERT操作,索引會降低它們的速度。這是因爲MySQL不僅要把改動數據寫入數據文件,而且它還要把這些改動寫入索引文件。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章