如何正確高效使用mysql數據庫的索引
1. 索引列上不能是使用表達式或函數
例:
- 索引列:out_date
- 查詢:select … from product where to_days(out_date) - to_days(current_date) <=30
- 優化:select … from product where out_date <= date_add(current_date,interval 30 day)
2. 前綴索引和索引列的選擇性
- B-tree索引對鍵值的大小有限制,Innodb引擎索引鍵值大小不能超過767個字節,MyISAM引擎索引鍵值不能超過1000字節,如果字符串長度超過此限制則無法對該列創建索引,即使對不超限制的長字符串能創建索引,查詢效率也會受到限制。所以Mysql支持對字符串的前綴創建索引,指定索引列的寬度,這樣大大節約索引空間,提高索引的查詢效率。
- 例:CREATE INDEX index_name ON table(col_name(n))。
- 索引的選擇性:索引的選擇性是不重複的索引值和表的記錄數的比值。索引的選擇性越高,使用索引查詢的效率就越高。
- 前綴索引只取了索引列的部分數據,索引的選擇性就會降低,所以使用前綴創建索引時,既要控制索引的長度,也要保證索引的選擇性不能太差。
3. 聯合索引
- Mysql 5.0以前,每一個查詢只能使用一個索引,對於多列的查詢條件,並不能使用每一列的索引;在Mysql5.0以後提出了索引合併的概念,在一個查詢中可以使用多個列上的獨立索引進行合併過濾,但需要更多磁盤I/O和內存來緩存數據,所以這也不是好的優化方式。所以,相比較多個列中創建單獨索引,創建聯合索引是個好的優化方法。
- 如何選擇聯合索引的順序
1. 經常會被使用到的列優先,放在聯合索引的最左邊
2. 選擇性高的列優先,選擇性越高,查詢效率越快(選擇性差的列不適合做索引,比如,性別,只有男,女,可能被Mysql優化器忽略)
3. 寬度小的列優先,寬度小,佔用的內存就小,查詢效率就高
4. 覆蓋索引
- 覆蓋索引:包含所有需要查詢字段的索引就是覆蓋索引,所有字段包括select中的字段,where條件中的字段,group by中的字段,order by 中的字段。
- 優點:
1. 可以優化緩存,減少磁盤I/O操作
2. 減少隨機I/O,變隨機IO爲順序IO
3. 可以避免對Innodb主鍵索引的二次查詢
4. 可以避免MyISAM表進行系統調用 - 無法使用覆蓋索引的情況
1. 存儲引擎不支持覆蓋索引
2. 查詢中使用了太多的列
3. 使用了雙%的like索引
5. 使用索引掃描來優化排序
- 索引的列順序和order by子句的順序完全一樣
- 索引中所有列的方向(升序和降序)和order by子句的順序完全一樣
- order by中的字段全部在關聯表中的第一張表中
6. 刪除重複和冗餘的索引
- primary key(id),unique key(id),index(id)
- index(a,b),index(a)
- primary key(id),index(a,id)
7. 更新索引統計信息及減少索引碎片
- analyze table table_name
- optimize table table_name(容易鎖表,使用需謹慎!)