一 何種查詢支持索引?1.何種查詢支持索引?
2.注意事項和建議
1 MySQL 目前支持前導列
就目前來說,mysql 暫時只支持最左前綴原則進行篩選。例子:創建復合索引 create index idx_a_b_c on tb1(a,b,c)只有使用如下條件才可能應用到這個復合索引1.where a=?2.where a =?and b =?3.where a =?and b =?and c =?但4.where a =?and c =?只會使用到mysql 索引 a 列的信息
2.索引列上的范圍查找
對於某個條件進行范圍查找時,如果這個列上有索引,且使用where... between and...>,<等范圍操作,那么可能用到索引范圍查找,如果索引范圍查找的成本太高,數據庫可能會選擇全表掃描的方式。注意in不屬於范圍查找的范疇
3.join 列
在聯合查詢兩個表時,比如查詢語句為select a.col1,b.col2 from a join b on a.id = b.id,其中id 為兩個表的主鍵,如果a是小表,那么a 就被視為驅動表,那么數據庫可能全表掃描a 表,並用 a表的每個id 去探測b表的索引查詢匹配的記錄。
4.where 子句
形如:where a =?and b =?and c>1000where a =?and b =?and c =?and d>1000where子句的條件列是復合索引前面的索引列+另一個列的范圍查找 create index idx_a_b_c_d on tb1(a,b,c,d);形如:where a =?and b =?and c>1000where a =?and b =?and c =?and d>1000才會用到這個索引下面兩個查詢:where a =?and b =?and c>10000and d<10000這個例子中d d >10000這個操作不會走索引where a >?and b =?and c>10000and d<10000這個例子中a列上有范圍查找,那么b、c、d列上的索引信息都不能被利用原則,創建索引,考慮把復合索引的范圍查找放到最后。
5.mysql 優化器
mysql 優化器會做一些特殊優化,比如對於索引查找max(索引列)可以直接進行定位。遇到max,min 是可以在列上做索引。
二 注意事項和建議
1.where 條件中的索引列不能是表達式的一部分,mysql 不支持函數索引
2.InnoDB 二級索引底層葉子極點存儲的是索引+主鍵值
InnoDB的非主鍵索引存儲的不是實際的記錄的指針,而是主鍵的值,所以主鍵最好是整數型,如自增ID ,基於主鍵存取數據是最高效的,使用二級索引存取數據則需要進行二次索引查找。
3.索引盡量是高選擇性的
而且要留意基數值,基數值指的是一個列中不同值的個數,顯然,最大基數意味着該列中的每個值都是唯一的,最小基數意味着該列中的所有值都是相同的,索引列的基數相對於表的行數較高時,也就重復值更少,索引的工作效果更好。有種情況雖然基數很小,但由於數據分布很不均勻因此也會導致某些記錄數很小,那么這種情況也適合建立索引加速查找這部分數據。
4.使用更短的索引
可以考慮前綴索引,但應確保選擇的前綴的長度可以保證大部分值是唯一的。如:alter table test add key(col(6))衡量不同前綴索引唯一值比例。select count(distinct left(col_name,5))/count(*)As sele5,select count(distinct left(col_name,6))/count(*)As sele6,select count(distinct left(col_name,7))/count(*)As sele7,select count(distinct left(col_name,8))/count(*)As sele8,select count(distinct left(col_name,9))/count(*)As sele9 from table_name;
5.避免創建過多的索引
索引過多可能會浪費大量空間尤其本身字段量較大的字符串,索引過多可能會浪費空間,且降低修改數據的速度,所以,不要創建過多的索引,也不要創建重復的索引。
6.如果是唯一值得列,創建唯一索引會更佳,也可以確保不會出現重復數據.
7.使用覆蓋索引能大大提高性能
覆蓋索引:所有數據都可以從索引中得到,而不需要去讀物理記錄。例如某個復合索引idx_a_b_c 建立在表tb1 的 a、b、c 列上,那么對於如下的sql 語句select a,b from tb1 where a =?and b =?and c =? mysql可以直接從索引idx_a_b_c 中獲取數據。使用覆蓋索引也可以避免二次索引查找。使用explain 命令輸出查詢計划,如果extra列是“using index ”那就表示使用的是覆蓋索引。
8.利用索引來排序
mysql 有兩種方式可以產生有序結果,一種是使用文件排序,另一種是掃描有序的索引,我們盡量使用索引來排序注意事項:1.盡量保證索引列和order by的列相同,且各列按照相同的順序排序。比如在表table1 的復合索引idx_a_b_c(創建在a,b,c上);如:select*from table1 order by a,b,c;select*from table1 where a=?and b =? order by c 以上查詢都可以利用有序索引來加速檢索順序。2.如果連接多張表,那么order by引用的列需要再表連接順序的首張表內。
9 添加冗余索引需要權衡:
如果一個索引column A 那么一個新的索引(columnA,columnB)就是冗余索引一般情況下不論是新增冗余索引,還是擴展原索引為冗余索引,都會導致索引文件的增大,並且增加了維護索引的開銷。比如更改了列值,並且在此列上建立了索引,那么這個列值更改之后,索引是要進行重新排序的。
