mysql索引總結----mysql 索引類型以及建立

文章歸屬:http://feiyan.info/16.html,我想本身去寫了,可是發現此君總結的很是詳細。直接搬過來了html

關於MySQL索引的好處,若是正確合理設計而且使用索引的MySQL是一輛蘭博基尼的話,那麼沒有設計和使用索引的MySQL就是一我的力三輪車。對於沒有索引的表,單表查詢可能幾十萬數據就是瓶頸,而一般大型網站單日就可能會產生幾十萬甚至幾百萬的數據,沒有索引查詢會變的很是緩慢。仍是以WordPress來講,其多個數據表都會對常常被查詢的字段添加索引,好比wp_comments表中針對5個字段設計了BTREE索引。前端

一個簡單的對比測試

以我去年測試的數據做爲一個簡單示例,20多條數據源隨機生成200萬條數據,平均每條數據源都重複大概10萬次,表結構比較簡單,僅包含一個自增ID,一個char類型,一個text類型和一個int類型,單表2G大小,使用MyIASM引擎。開始測試未添加任何索引。mysql

執行下面的SQL語句:sql

1 mysql> SELECT id,FROM_UNIXTIME(timeFROM article WHERE a.title='測試標題'

查詢須要的時間很是恐怖的,若是加上聯合查詢和其餘一些約束條件,數據庫會瘋狂的消耗內存,而且會影響前端程序的執行。這時給title字段添加一個BTREE索引:數據庫

1 mysql> ALTER TABLE article ADD INDEX index_article_title ON title(200);

再次執行上述查詢語句,其對比很是明顯:數據庫設計

 

MySQL索引的概念

索引是一種特殊的文件(InnoDB數據表上的索引是表空間的一個組成部分),它們包含着對數據表裏全部記錄的引用指針。更通俗的說,數據庫索引比如是一本書前面的目錄,能加快數據庫的查詢速度。上述SQL語句,在沒有索引的狀況下,數據庫會遍歷所有200條數據後選擇符合條件的;而有了相應的索引以後,數據庫會直接在索引中查找符合條件的選項。若是咱們把SQL語句換成「SELECT * FROM article WHERE id=2000000」,那麼你是但願數據庫按照順序讀取完200萬行數據之後給你結果仍是直接在索引中定位呢?上面的兩個圖片鮮明的用時對比已經給出了答案(注:通常數據庫默認都會爲主鍵生成索引)。oop

索引分爲聚簇索引和非聚簇索引兩種,聚簇索引是按照數據存放的物理位置爲順序的,而非聚簇索引就不同了;聚簇索引能提升多行檢索的速度,而非聚簇索引對於單行的檢索很快。性能

MySQL索引的類型

1. 普通索引測試

這是最基本的索引,它沒有任何限制,好比上文中爲title字段建立的索引就是一個普通索引,MyIASM中默認的BTREE類型的索引,也是咱們大多數狀況下用到的索引。大數據

01 –直接建立索引
02 CREATE INDEX index_name ON table(column(length))
03 –修改表結構的方式添加索引
04 ALTER TABLE table_name ADD INDEX index_name ON (column(length))
05 –建立表的時候同時建立索引
06 CREATE TABLE `table` (
07 `id` int(11) NOT NULL AUTO_INCREMENT ,
08 `title` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
09 `content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
10 `timeint(10) NULL DEFAULT NULL ,
11 PRIMARY KEY (`id`),
12 INDEX index_name (title(length))
13 )
14 –刪除索引
15 DROP INDEX index_name ON table

2. 惟一索引

與普通索引相似,不一樣的就是:索引列的值必須惟一,但容許有空值(注意和主鍵不一樣)。若是是組合索引,則列值的組合必須惟一,建立方法和普通索引相似。

01 –建立惟一索引
02 CREATE UNIQUE INDEX indexName ON table(column(length))
03 –修改表結構
04 ALTER TABLE table_name ADD UNIQUE indexName ON (column(length))
05 –建立表的時候直接指定
06 CREATE TABLE `table` (
07 `id` int(11) NOT NULL AUTO_INCREMENT ,
08 `title` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
09 `content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
10 `timeint(10) NULL DEFAULT NULL ,
11 PRIMARY KEY (`id`),
12 UNIQUE indexName (title(length))
13 );

3. 全文索引(FULLTEXT)

MySQL從3.23.23版開始支持全文索引和全文檢索,FULLTEXT索引僅可用於 MyISAM 表;他們能夠從CHAR、VARCHAR或TEXT列中做爲CREATE TABLE語句的一部分被建立,或是隨後使用ALTER TABLE 或CREATE INDEX被添加。////對於較大的數據集,將你的資料輸入一個沒有FULLTEXT索引的表中,而後建立索引,其速度比把資料輸入現有FULLTEXT索引的速度更爲快。不過切記對於大容量的數據表,生成全文索引是一個很是消耗時間很是消耗硬盤空間的作法。

01 –建立表的適合添加全文索引
02 CREATE TABLE `table` (
03 `id` int(11) NOT NULL AUTO_INCREMENT ,
04 `title` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
05 `content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
06 `timeint(10) NULL DEFAULT NULL ,
07 PRIMARY KEY (`id`),
08 FULLTEXT (content)
09 );
10 –修改表結構添加全文索引
11 ALTER TABLE article ADD FULLTEXT index_content(content)
12 –直接建立索引
13 CREATE FULLTEXT INDEX index_content ON article(content)

4. 單列索引、多列索引

多個單列索引與單個多列索引的查詢效果不一樣,由於執行查詢時,MySQL只能使用一個索引,會從多個索引中選擇一個限制最爲嚴格的索引。

5. 組合索引(最左前綴)

平時用的SQL查詢語句通常都有比較多的限制條件,因此爲了進一步榨取MySQL的效率,就要考慮創建組合索引。例如上表中針對title和time創建一個組合索引:ALTER TABLE article ADD INDEX index_titme_time (title(50),time(10))。創建這樣的組合索引,實際上是至關於分別創建了下面兩組組合索引:

–title,time

–title

爲何沒有time這樣的組合索引呢?這是由於MySQL組合索引「最左前綴」的結果。簡單的理解就是隻從最左面的開始組合。並非只要包含這兩列的查詢都會用到該組合索引,以下面的幾個SQL所示:

1 –使用到上面的索引
2 SELECT FROM article WHREE title='測試' AND time=1234567890;
3 SELECT FROM article WHREE utitle='測試';
4 –不使用上面的索引
5 SELECT FROM article WHREE time=1234567890;
MySQL索引的優化

上面都在說使用索引的好處,但過多的使用索引將會形成濫用。所以索引也會有它的缺點:雖然索引大大提升了查詢速度,同時卻會下降更新表的速度,如對錶進行INSERT、UPDATE和DELETE。由於更新表時,MySQL不只要保存數據,還要保存一下索引文件。創建索引會佔用磁盤空間的索引文件。通常狀況這個問題不太嚴重,但若是你在一個大表上建立了多種組合索引,索引文件的會膨脹很快。索引只是提升效率的一個因素,若是你的MySQL有大數據量的表,就須要花時間研究創建最優秀的索引,或優化查詢語句。下面是一些總結以及收藏的MySQL索引的注意事項和優化方法。

1. 什麼時候使用匯集索引或非彙集索引?

動做描述 使用匯集索引 使用非彙集索引
列常常被分組排序 使用 使用
返回某範圍內的數據 使用 不使用
一個或極少不一樣值 不使用 不使用
小數目的不一樣值 使用 不使用
大數目的不一樣值 不使用 使用
頻繁更新的列 不使用 使用
外鍵列 使用 使用
主鍵列 使用 使用
頻繁修改索引列 不使用 使用

事實上,咱們能夠經過前面彙集索引和非彙集索引的定義的例子來理解上表。如:返回某範圍內的數據一項。好比您的某個表有一個時間列,剛好您把聚合索引創建在了該列,這時您查詢2004年1月1日至2004年10月1日之間的所有數據時,這個速度就將是很快的,由於您的這本字典正文是按日期進行排序的,聚類索引只須要找到要檢索的全部數據中的開頭和結尾數據便可;而不像非彙集索引,必須先查到目錄中查到每一項數據對應的頁碼,而後再根據頁碼查到具體內容。其實這個具體用法我還不是很理解,只能等待後期的項目開發中慢慢學學了。

2. 索引不會包含有NULL值的列

只要列中包含有NULL值都將不會被包含在索引中,複合索引中只要有一列含有NULL值,那麼這一列對於此複合索引就是無效的。因此咱們在數據庫設計時不要讓字段的默認值爲NULL。

3. 使用短索引

對串列進行索引,若是可能應該指定一個前綴長度。例如,若是有一個CHAR(255)的列,若是在前10個或20個字符內,多數值是唯一的,那麼就不要對整個列進行索引。短索引不只能夠提升查詢速度並且能夠節省磁盤空間和I/O操做。

4. 索引列排序

MySQL查詢只使用一個索引,所以若是where子句中已經使用了索引的話,那麼order by中的列是不會使用索引的。所以數據庫默認排序能夠符合要求的狀況下不要使用排序操做;儘可能不要包含多個列的排序,若是須要最好給這些列建立複合索引。

5. like語句操做

通常狀況下不鼓勵使用like操做,若是非使用不可,如何使用也是一個問題。like 「%aaa%」 不會使用索引而like 「aaa%」可使用索引。

6. 不要在列上進行運算

例如:select * from users where YEAR(adddate)<2007,將在每一個行上進行運算,這將致使索引失效而進行全表掃描,所以咱們能夠改爲:select * from users where adddate<’2007-01-01′。關於這一點能夠圍觀:一個單引號引起的MYSQL性能損失。

最後總結一下,MySQL只對一下操做符才使用索引:<,<=,=,>,>=,between,in,以及某些時候的like(不以通配符%或_開頭的情形)。而理論上每張表裏面最多可建立16個索引,不過除非是數據量真的不少,不然過多的使用索引也不是那麼好玩的,好比我剛纔針對text類型的字段建立索引的時候,系統差點就卡死了。

總結一下:

修改原有字段名稱及類型:
ALTER TABLE bulletin CHANGE uid username VARCHAR(50) NOT NULL DEFAULT '';

添加新字段:

alter table bulletin add citycode varchar(6) not null default 0; # 城市代碼

1.建立數據庫時設置編碼

create database test character set utf8;

2.建立表時設置編碼

create table test(id int primary key)DEFAULT charset=utf8;

3.修改數據庫編碼

alter database test character set utf8;

4.修改表默認編碼

alter table test character set utf8;

5.修改字段編碼

alter table test modify col_name varchar(50) CHARACTER SET utf8;

---------添加索引方法---------

1.添加PRIMARY KEY(主鍵索引)

mysql>ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` )

2.添加UNIQUE(惟一索引)

mysql>ALTER TABLE `table_name` ADD UNIQUE (

`column`

)


3.添加INDEX(普通索引)
mysql>ALTER TABLE `table_name` ADD INDEX index_name ( `column` )


4.添加FULLTEXT(全文索引)
mysql>ALTER TABLE `table_name` ADD FULLTEXT (
`column`
)

5.添加多列索引 mysql>ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )
相關文章
相關標籤/搜索