如何正確合理的建立MYSQL數據庫索引

普通MySQL運行,數據量和訪問量不大的話,是足夠快的,但是當數據量和訪問量劇增的時候,那麼就會明顯發現MySQL很慢,甚至down掉,那麼就要考慮優化我們的MySQL瞭。其中優化MYSQL的一個重要環節就是為數據庫建立正確合理的索引。
 
如果沒有索引,執行查詢時MySQL必須從第一個記錄開始掃描整個表的所有記錄,直至找到符合要求的記錄。表裡面的記錄數量越多,這個操作的代價就越高。如果作為搜索條件的列上已經創建瞭索引,MySQL無需掃描任何記錄即可迅速得到目標記錄所在的位置。也就是說索引可以大大減少數據庫管理系統查找數據的時間。
索引有哪些優點?
 
1、  通過創建唯一性索引,可以保證數據庫表中每一 行數據的唯一性。
 
2、  可以大大加快數據的檢索速度,這也是創建索引 的最主要原因。
 
3、  可以加速表和表之間的連接,這在實現數據的參 考完整性方面特別有意義。
 
4、  在使用分組和排序子句進行數據檢索時,同樣可 以顯著減少查詢中分組和排序的時間。
索引有哪些缺點?
 
1、  創建索引和維護索引要耗費時間,這種時間隨著 數據量的增加而增加。
 
2、  除瞭數據表占數據空間之外,每一個索引還要占 一定的物理空間,如果要建立聚簇索引,需要的空間就會更大。
 
3、  當對表中的數據進行增加、刪除和修改的時候, 索引也要動態的維護,這樣就降低瞭數據的維護速度。
索引有哪些類型?
 
1、 普通索引
 
這是最基本的索引類 型,而且它沒有唯一性之類的限制。
 
2、 唯一性索引
 
這種索引和前面的“普通索引”基本相同,但有一個區別:索引列的所有值都隻能出現一次,即必須唯一。
 
3、主鍵
 
它是一種特殊 的唯一索引,不允許有空值。
 
4、全文索引
 
MySQL從3.23.23版開始支持全 文索引和全文檢索。
單列索引和組合索引:
 
單列索引就是 把索引單獨建立在一個字段上。
 
組合索引復合索引就是一個索引創建在兩個列或者多個列上。在搜索時,當兩個或者多個列作為一個關鍵值時,最好在這些列上創建復合索引。
建立和使用索引有哪些註意事項:
 
1、           索引要建立在經常進行select操作的字段上。這是因為,如果這些列很少用到,那麼有無索引並不能明顯改變查詢速度。相反,由於增加瞭索引,反而降低瞭系統的維護速度和增大瞭空間需求。
 
2、           索引要建立在值比較唯一的 字段上。這樣做才是發揮索引的最大效果。,比如主鍵的id字段,唯 一的名字name字段等等。如果索引建立在唯一值比較少的字段,比如性別gender字段,寥寥無幾的類別字段等,剛索引幾乎沒有任何意義。
 
3、           對於那些定義為text、image和bit數據類型的列不應該增加索引。因為這些列的數據量要麼相當大,要麼取值很少。
 
4、           當修改性能遠遠大於檢索性能時,不應該創建索引。修改性能和檢索性能是互相矛盾的。當增加索引時,會提高檢索性能,但是會降低修改性能。當減少索引時,會提高修改性能,降低檢索性能。因此,當修改性能遠遠大於檢索性能時,不應該創建索引。
 
5、           在WHERE和JOIN中出現的列需要建立索引。
 
6、           在以通配符% 和_ 開頭作查詢時,MySQL索引是無效的。但是這樣索引是有效的:select * from tbl1 where name like 'xxx%',所以謹慎的寫你的SQL是很重要的。
 
 
 
用一個例子詳細說明單列索引與組合索引的區別及索引使用中的一些細節
 
建一個表:
    CREATE TABLE myIndex (
 
i_testID INT NOT NULL AUTO_INCREMENT,
 
vc_Name VARCHAR(50) NOT NULL,
 
vc_City VARCHAR(50) NOT NULL,
 
i_Age INT NOT NULL,
 
i_SchoolID INT NOT NULL,
 
PRIMARY KEY (i_testID)
 
);
 
   在這10000條記錄裡面7上8下地分佈瞭5條vc_Name="erquan"的記錄,隻不過city,age,school的組合各不相同。
  來看這條T-SQL:
    SELECT i_testID FROM myIndex WHERE vc_Name='erquan' AND vc_City='鄭 州' AND i_Age=25;
 
    首先考慮建單列索引:
    在vc_Name列上建立瞭索引。執行T-SQL時,MYSQL很快將目標鎖定在瞭vc_Name=erquan的5條記錄上,取出來放到一中間 結果集。在這個結果集裡,先排除掉vc_City不等於"鄭州"的記錄,再排除i_Age不等於25的記錄,最後篩選出唯一的符合條件的記錄。
 
    雖然在vc_Name上建立瞭索引,查詢時MYSQL不用掃描整張表,效率有所提高,但離我們的要求還有一定的距離。同樣的,在vc_City和i_Age分別建立的單列索引的效率相似。
 
    為瞭進一步榨取MySQL的效率,就要考慮建立組合索引。就是將vc_Name,vc_City,i_Age建到一個索引裡:
    ALTER TABLE myIndex ADD INDEX name_city_age (vc_Name(10),vc_City,i_Age);–註意瞭,建表時,vc_Name長度為50,這裡為什麼用10呢?因為一般情 況下名字的長 度不會超過10,這樣會加速索引查詢速度,還會減少索引文件的大小,提高INSERT的更新速度。
 
    執行T-SQL時,MySQL無須掃描任何記錄就到找到唯一的記錄!!
 
    肯定有人要問瞭,如果分別在vc_Name,vc_City,i_Age上建立單列索引,讓該表有3個單列索引,查詢 時和上述的組合索引效率一樣 吧?嘿嘿,大不一樣,遠遠低於 我們的組合索引~~雖然此時有瞭三個索引,但MySQL隻能用到其中的那個它認為似乎是最有效率的單列索引。
 
    建立這樣的組合索引,其實是相當於分別建立瞭
        vc_Name,vc_City,i_Age
        vc_Name,vc_City
        vc_Name
    這樣的三個組合索引!為什麼沒有vc_City,i_Age等這樣的組合索引呢?這是因為mysql組合索引"最左前綴"的結果。簡單的理解就是隻從最左面的開始組合。並不是隻要包含這三列的查詢都會用到該組合索引,下面的幾個T-SQL會用到:
    SELECT * FROM myIndex WHREE vc_Name="erquan" AND vc_City="鄭州"
    SELECT * FROM myIndex WHREE vc_Name="erquan"
而下面幾個則不會 用到:
    SELECT * FROM myIndex WHREE i_Age=20 AND vc_City="鄭州"
    SELECT * FROM myIndex WHREE vc_City="鄭州"

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *