最近想總結(jié)下mysql索引的知識點,搜索資料后發(fā)現(xiàn),mysql索引是個很大的學問。今天就在應用層面去學習如何使用索引, MySQL索引的建立對于MySQL的高效運行是很重要的,索引可以大大提高MySQL的檢索速度。
打個比方,如果合理的設(shè)計且使用索引的MySQL是一輛蘭博基尼的話,那么沒有設(shè)計和使用索引的MySQL就是一個人力三輪車。
索引類型:定義表索引的類型
normal索引是最近本的索引,沒有對唯一性的限制
unique索引和normal類似,只是索引列的全部值必須只能出現(xiàn)一次
full text索引用于mysql全文索引,用于在一篇文章中,檢索文本信息。InnoDB不支持,Myisam支持性能比較好,一般在 CHAR、VARCHAR 或 TEXT 列上創(chuàng)建。
主鍵索引 針對主鍵的檢索,設(shè)置某字段為primary key主鍵
主鍵就是唯一索引的一種,主鍵要求建表時指定,一般用auto_increatment列,關(guān)鍵字是primary key
索引方法:當創(chuàng)建索引時,指定索引類型,btree或者hash(全文搜索的時候沒有)
索引分單列索引和組合索引。單列索引,即一個索引只包含單個列,一個表可以有多個單列索引,但這不是組合索引。組合索引,即一個索引包含多個列。
創(chuàng)建多列索引的列子:
create table test3 (id int not null primary key auto_increment, account int(12) not null default '',account_type int(2) not null,INDEX(account,account_type))type=myisam;
注意:INDEX(a, b, c)可以當做a或(a, b)的索引來使用,但和b、c或(b,c)的索引來使用這是一個最左前綴的優(yōu)化方法。
創(chuàng)建索引時,你需要確保該索引是應用在 SQL 查詢語句的條件(一般作為 WHERE 子句的條件)。
實際上,索引也是一張表,該表保存了主鍵與索引字段,并指向?qū)嶓w表的記錄。
上面都在說使用索引的好處,但過多的使用索引將會造成濫用。因此索引也會有它的缺點:雖然索引大大提高了查詢速度,同時卻會降低更新表的速度,如對表進行INSERT、UPDATE和DELETE。因為更新表時,MySQL不僅要保存數(shù)據(jù),還要保存一下索引文件。
建立索引會占用磁盤空間的索引文件。
這是最基本的索引,它沒有任何限制。它有以下幾種創(chuàng)建方式:
CREATE INDEX indexName ON mytable(username(length));
如果是CHAR,VARCHAR類型,length可以小于字段實際長度;如果是BLOB和TEXT類型,必須指定 length。
nativecat創(chuàng)建索引
ALTER table tableName ADD INDEX indexName(columnName)
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, INDEX [indexName] (username(length)) );
DROP INDEX [indexName] ON mytable;
它與前面的普通索引類似,不同的就是:索引列的值必須唯一,但允許有空值。如果是組合索引,則列值的組合必須唯一。它有以下幾種創(chuàng)建方式:
CREATE UNIQUE INDEX indexName ON mytable(username(length))
ALTER table mytable ADD UNIQUE [indexName] (username(length))
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, UNIQUE [indexName] (username(length)) );
有四種方式來添加數(shù)據(jù)表的索引:
ALTER TABLE tbl_name ADD PRIMARY KEY (column_list): 該語句添加一個主鍵,這意味著索引值必須是唯一的,且不能為NULL。
ALTER TABLE tbl_name ADD UNIQUE index_name (column_list): 這條語句創(chuàng)建索引的值必須是唯一的(除了NULL外,NULL可能會出現(xiàn)多次)。
ALTER TABLE tbl_name ADD INDEX index_name (column_list): 添加普通索引,索引值可出現(xiàn)多次。
ALTER TABLE tbl_name ADD FULLTEXT index_name (column_list):該語句指定了索引為 FULLTEXT ,用于全文索引。
以下實例為在表中添加索引。
mysql> ALTER TABLE testalter_tbl ADD INDEX (c);
你還可以在 ALTER 命令中使用 DROP 子句來刪除索引。嘗試以下實例刪除索引:
mysql> ALTER TABLE testalter_tbl DROP INDEX c;
主鍵只能作用于一個列上,添加主鍵索引時,你需要確保該主鍵默認不為空(NOT NULL)。實例如下:
mysql> ALTER TABLE testalter_tbl MODIFY i INT NOT NULL; mysql> ALTER TABLE testalter_tbl ADD PRIMARY KEY (i);
你也可以使用 ALTER 命令刪除主鍵:
mysql> ALTER TABLE testalter_tbl DROP PRIMARY KEY;
刪除主鍵時只需指定PRIMARY KEY,但在刪除索引時,你必須知道索引名。
你可以使用 SHOW INDEX 命令來列出表中的相關(guān)的索引信息??梢酝ㄟ^添加 \G 來格式化輸出信息。
嘗試以下實例:
mysql> SHOW INDEX FROM table_name; ........
合理建立索引
1.在表中有where和join中出現(xiàn)的列需要建立索引,mysql只針對<,<=,=,>,>=,between,in以及l(fā)ike才會使用索引
2.表中某屬性的字段(如user_key)是唯一的不能為空??梢越nique索引。
3.索引不是越多越好,如果索引過多,更新表數(shù)據(jù)時候也會很耗時。
mysql建索引的幾大原則
1.選擇唯一性索引
唯一性索引的值是唯一的,可以更快速的通過該索引來確定某條記錄。例如,學生表中學號是具有唯一性的字段。為該字段建立唯一性索引可以很快的確定某個學生的信息。如果使用姓名的話,可能存在同名現(xiàn)象,從而降低查詢速度。
2.為經(jīng)常需要排序、分組和聯(lián)合操作的字段建立索引
經(jīng)常需要ORDER BY、GROUP BY、DISTINCT和UNION等操作的字段,排序操作會浪費很多時間。如果為其建立索引,可以有效地避免排序操作。
3.為常作為查詢條件的字段建立索引
如果某個字段經(jīng)常用來做查詢條件,那么該字段的查詢速度會影響整個表的查詢速度。因此,為這樣的字段建立索引,可以提高整個表的查詢速度。
4.限制索引的數(shù)目
索引的數(shù)目不是越多越好。每個索引都需要占用磁盤空間,索引越多,需要的磁盤空間就越大。修改表時,對索引的重構(gòu)和更新很麻煩。越多的索引,會使更新表變得很浪費時間。
5.盡量使用數(shù)據(jù)量少的索引
如果索引的值很長,那么查詢的速度會受到影響。例如,對一個CHAR(100)類型的字段進行全文檢索需要的時間肯定要比對CHAR(10)類型的字段需要的時間要多。
6.盡量使用前綴來索引
如果索引字段的值很長,最好使用值的前綴來索引。例如,TEXT和BLOG類型的字段,進行全文檢索會很浪費時間。如果只檢索字段的前面的若干個字符,這樣可以提高檢索速度。
7.刪除不再使用或者很少使用的索引
表中的數(shù)據(jù)被大量更新,或者數(shù)據(jù)的使用方式被改變后,原有的一些索引可能不再需要。數(shù)據(jù)庫管理員應當定期找出這些索引,將它們刪除,從而減少索引對更新操作的影響。
8 . 最左前綴匹配原則,非常重要的原則。
mysql會一直向右匹配直到遇到范圍查詢(>、<、between、like)就停止匹配,比如a 1=”” and=”” b=”2” c=”“> 3 and d = 4 如果建立(a,b,c,d)順序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引則都可以用到,a,b,d的順序可以任意調(diào)整。
9 .=和in可以亂序。
比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意順序,mysql的查詢優(yōu)化器會幫你優(yōu)化成索引可以識別的形式
10 . 盡量選擇區(qū)分度高的列作為索引。
區(qū)分度的公式是count(distinct col)/count(*),表示字段不重復的比例,比例越大我們掃描的記錄數(shù)越少,唯一鍵的區(qū)分度是1,而一些狀態(tài)、性別字段可能在大數(shù)據(jù)面前區(qū)分度就 是0,那可能有人會問,這個比例有什么經(jīng)驗值嗎?使用場景不同,這個值也很難確定,一般需要join的字段我們都要求是0.1以上,即平均1條掃描10條 記錄
11 .索引列不能參與計算,保持列“干凈”。
比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很簡單,b+樹中存的都是數(shù)據(jù)表中的字段值,但進行檢索時,需要把所有元素都應用函數(shù)才能比較,顯然成本 太大。所以語句應該寫成create_time = unix_timestamp(’2014-05-29’);
12 .盡量的擴展索引,不要新建索引。
比如表中已經(jīng)有a的索引,現(xiàn)在要加(a,b)的索引,那么只需要修改原來的索引即可
注意:選擇索引的最終目的是為了使查詢的速度變快。上面給出的原則是最基本的準則,但不能拘泥于上面的準則。讀者要在以后的學習和工作中進行不斷的實踐。根據(jù)應用的實際情況進行分析和判斷,選擇最合適的索引方式。
如對本文有疑問,請?zhí)峤坏浇涣髡搲?,廣大熱心網(wǎng)友會為你解答??! 點擊進入論壇