MySQL的索引及优化方案
目錄
- 索引的概念
- 索引的分類
- 索引的機制
- 索引的優缺點
- 在哪些表上適合使用索引
- 索引的使用
- 索引使用注意事項
- 各個索引區別
- 索引優化策略
索引的概念
通過給字段添加索引可以提高數據的讀取速度,提高項目的并發能力和抗壓能力。索引優化是mysql中的一種優化方式。索引的作用相當于圖書的目錄,可以根據目錄中的頁碼快速找到所需的內容
索引的分類
聯合索引(復合索引)
- 聯合索引其實很簡單,相對于一般索引只有一個字段,聯合索引可以為多個字段創建一個索引
- 它的原理也很簡單,比如,我們在(a,b,c)字段上創建一個聯合索引,則索引記錄會首先按照A字段排序,然后再按照B字段排序然后再是C字段
- 其實聯合索引的查找就跟查字典是一樣的,先根據第一個字母查,然后再根據第二個字母查
- 或者只根據第一個字母查,但是不能跳過第一個字母從第二個字母開始查。這就是所謂的最左前綴原理
- 聯合索引的特點就是:
- 1)第一個字段一定是有序的
- 2)當第一個字段值相等的時候,第二個字段又是有序的,比如下表中當A=2時所有B的值是有序排列的,依次類推,當同一個B值得所有C字段是有序排列的
最左前綴查詢舉例
'''最左前綴原理'''#### 1、以下的查詢方式都可以用到索引 ''' select * from table where a=1; select * from table where a=1 and b=2; select * from table where a=1 and b=2 and c=3; 上面三個查詢按照 (a ), (a,b ),(a,b,c )的順序都可以利用到索引,這就是最左前綴匹配。 '''#### 2、如果查詢語句是: ''' select * from table where a=1 and c=3; 那么只會用到索引a。 '''#### 3、這樣不會用的索引 ''' select * from table where b=2 and c=3; 因為沒有用到最左前綴a,所以這個查詢是用戶到索引的。 '''前綴索引
1. 前綴索引就是用列的前綴代替整個列作為索引key,當前綴長度合適時,可以做到既使得前綴索引的選擇性接近全列索引
2. 同時因為索引key變短而減少了索引文件的大小和維護開銷。
3. 一般來說以下情況可以使用前綴索引:
1)字符串列(varchar,char,text等),需要進行全字段匹配或者前匹配。也就是=‘xxx’ 或者 like ‘xxx%’
2)字符串本身可能比較長,而且前幾個字符就開始不相同。(比如:收件地址、外國人的姓名)
4. MySQL 前綴索引能有效減小索引文件的大小,提高索引的速度。
5. 但是前綴索引也有它的壞處:MySQL 不能在 ORDER BY 或 GROUP BY 中使用前綴索引,也不能把它們用作覆蓋索引(Covering Index)。
主鍵索引
當把一張表的某列設置為主鍵的時候,則該列就是主鍵索引。
主鍵是一種唯一性索引,但它必須指定為 primary key,每個表只能有一個主鍵。
當一張表,把某個列設為主鍵的時候,則該列就是主鍵索引
唯一索引
當表的某列被指定為unique約束時,這列就是唯一索引
索引列的所有值都只能出現一次,即必須唯一,值可以為空。
create table test (id int primary key auto_increment , name varchar(32) unique);test表中name就是唯一索引,唯一索引可以有多個null,不能是重復的內容
相比主鍵索引,主鍵字段不能為null,也不能重復
普通索引
一般來說,普通索引是先創建表,然后創建普通索引。
基本的索引類型,值可以為空,沒有唯一性的限制。
普通索引一般是在建表后再添加的,
create index 索引名 on table_name(column1,column2);alter table table_name add index 索引名(column1,column2);全文索引
全文索引,主要是針對文件,比如文章的索引全文索引針對MyISAM有用,針對innodb沒有用
? 如果希望通過關鍵字的匹配來進行查詢過濾,那么就需要基于相似度的查詢,而不是原來的精確數值比較。全文索引就是為這種場景設計的。
首先,全文索引主要針對文本文件,
全文索引的版本、存儲引擎、數據類型的支持情況
索引的機制
為什么我們添加完索引后查詢速度為變快?
傳統的查詢方法,是按照表的順序遍歷的,不論查詢幾條數據,mysql需要將表的數據從頭到尾遍歷一遍
在我們添加完索引之后,mysql一般通過btree算法生成一個索引文件,在查詢數據庫時,找到索引文件進行遍歷(折半查找大幅查詢效率),找到相應的鍵從而獲取數據
如何評價索引性能
- 一般來說,索引本身也很大,不可能全部存儲在內存中,因此索引往往以索引文件的形式存儲的磁盤上
- 這樣的話,索引查找過程中就要產生磁盤I/O消耗,相對于內存存取,I/O存取的消耗要高幾個數量級
- 所以評價一個數據結構作為索引的優劣最重要的指標就是在查找過程中磁盤I/O操作次數的漸進復雜度
- 換句話說,索引的結構組織要盡量減少查找過程中磁盤I/O的存取次數
為什么不建議使用過長的字段作為主鍵
1. 例如知道了InnoDB的索引實現后,就很容易明白為什么不建議使用過長的字段作為主鍵
2. 因為所有輔助索引都引用主索引,過長的主索引會令輔助索引變得過大。
3. 再例如,用非單調的字段作為主鍵在InnoDB中不是個好主意,因為InnoDB數據文件本身是一顆B+Tree,
4. 非單調的主鍵會造成在插入新記錄時數據文件為了維持B+Tree的特性而頻繁的分裂調整,十分低效,而使用自增字段作為主鍵則是一個很好的選擇。
索引的優缺點
優點:
創建索引可以大大提高系統的性能。
- 通過創建唯一性索引,可以保證數據庫表中每一行數據的唯一性。
- 可以大大加快數據的檢索速度,這也是創建索引的最主要的原因。
- 可以加速表和表之間的連接,特別是在實現數據的參考完整性方面特別有意義。
- 在使用分組和排序子句進行數據檢索時,同樣可以顯著減少查詢中分組和排序的時間。
- 通過使用索引,可以在查詢的過程中,使用優化隱藏器,提高系統的性能。
缺點
- 創建索引和維護索引要耗費時間,這種時間隨著數據量的增加而增加。
- 索引需要占物理空間,除了數據表占數據空間之外,每一個索引還要占一定的物理空間,如果要建立聚簇索引,那么需要的空間就會更大。
- 當對表中的數據進行增加、刪除和修改的時候,索引也要動態的維護,這樣就降低了數據的維護速度。
在哪些表上適合使用索引
滿足以下條件的字段,才應該創建索引
- 肯定在where條經常使用
- 該字段的內容不是唯一的幾個值
- 字段內容不是頻繁變化
索引的使用
索引使用原則
1、較頻繁的作為查詢條件字段應該創建索引
select * from emp where empno = 1;
2、唯一性太差的字段不適合單獨創建索引,即使頻繁作為查詢條件
select * from emp where sex = ‘男’
3、更新非常頻繁的字段不適合創建索引
select * from emp where logincount = 1
4、不會出現在WHERE子句中的字段不該創建索引
使用或不使用索引的情況
1. 下列幾種情況下有可能使用到索引
- 對于創建的多列索引,只要查詢條件使用了最左邊的列,索引一般就會被使用。
- 對于使用like的查詢,查詢如果是 ‘%aaa’ 不會使用到索引, ‘aaa%’ 會使用到索引
2. 下列的表將不使用索引
- 如果條件中有or,即使其中有條件帶索引也不會使用。
- 對于多列索引,不是使用的第一部分,則不會使用索引。
- like查詢是以%開頭
- 如果列類型是字符串,那一定要在條件中將數據使用引號引用起來。否則不使用索引。(添加時,字符串必須’’)
- 如果mysql估計使用全表掃描要比使用索引快,則不使用索引。
1、create [UNIQUE|FULLTEXT] index index_name on tbl_name (col_name
[(length)] [ASC | DESC] , ……);
2、alter table table_name ADD INDEX [index_name] (index_col_name,…)
1、DROP INDEX index_name ON tbl_name;
2、alter table table_name drop index index_name;
注:刪除主鍵(索引)比較特別: alter table t_b drop primary key;
#1 查看student表中有哪些索引
mysql> show index from student; #查看student表中有哪些索引
#2 創建最基本的的索引
mysql> create index index_name on student(name(32)); #將student中字段name創建成索引
#3 刪除索引的語法
mysql> drop index index_name on student;
注: 它與前面的普通索引類似,不同的就是:索引列的值必須唯一,但允許有空值
#1創建索引
mysql> create unique index index_name on student(name(32));
索引使用注意事項
比如我們對title,content 添加了復合索引
select * from table_name where title = ‘test’;會用到索引
select * from table_name where content = ‘test’;不會用到索引
各個索引區別
普通索引:最基本的索引,沒有任何限制
唯一索引:與"普通索引"類似,不同的就是:索引列的值必須唯一,但允許有空值。
主鍵索引:它 是一種特殊的唯一索引,不允許有空值。
全文索引:僅可用于 Myisam (米色母)表(默認表類型,如果執行大量的查詢比較適合。),針對較大的數據,生成全文索引很耗時也耗空間。
索引優化策略
MySQL的優化主要分為結構優化(Scheme optimization)和查詢優化(Query optimization)
索引優化的方式
# 1、最左前綴匹配原則,上面講到了 # 2、主鍵外鍵一定要建索引 # 3、對 where,on,group by,order by 中出現的列使用索引 # 4、盡量選擇區分度高的列作為索引,區分度的公式是count(distinct col)/count(*),表示字段不重復的比例, # 5、為較長的字符串使用前綴索引''' # 6、不要過多創建索引, 權衡索引個數與DML之間關系,DML也就是插入、刪除數據操作。這里需要權衡一個問題,建立索引的目的是為了提高查詢效率的,但建立的索引過多,會影響插入、刪除數據的速度,因為我們修改的表數據,索引也需要進行調整重建 '''''' # 7、對于like查詢,”%”不要放在前面。SELECT * FROMhoudunwangWHEREunameLIKE'后盾%' -- 走索引 SELECT * FROMhoudunwangWHEREunameLIKE "%后盾%" -- 不走索引 '''''' # 8、查詢where條件數據類型不匹配也無法使用索引 字符串與數字比較不使用索引; CREATE TABLEa(achar(10)); EXPLAIN SELECT * FROMaWHEREa="1" – 走索引 EXPLAIN SELECT * FROM a WHERE a=1 – 不走索引 正則表達式不使用索引,這應該很好理解,所以為什么在SQL中很難看到regexp關鍵字的原因總結
以上是生活随笔為你收集整理的MySQL的索引及优化方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL的主从复制主从同步
- 下一篇: MySQL数据库的优化