欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MySQL添加索引及添加字段并建立索引方式

 更新時間:2024年01月27日 15:42:17   作者:人間寥寥情難訴  
這篇文章主要介紹了MySQL添加索引及添加字段并建立索引方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

MySQL添加索引及字段并建立索引

添加字段并設(shè)置字段主鍵

alter table table_name drop primary key;
alter table table_name add column column2 varchar(10) NOT NULL COMMENT 'column2' AFTER column2;
alter table table_name add constraint user_test primary key(column_list); 

新建索引

使用CREATE語句創(chuàng)建索引:

  • 普通索引:
CREATE INDEX index_name ON table_name(column_name1,column_name2);
  • 唯一索引:
CREATE UNIQUE INDEX index_name ON table_name(column_name);
  • 主鍵索引:
CREATE PRIMARY KEY INDEX index_name ON table_name(column_name); 

使用ALTER TABLE語句創(chuàng)建索引:

  • 普通索引:
alter table table_name add index index_name (column_list);
  • 唯一索引:
alter table table_name add unique index_name (column_list);
  • 主鍵索引:
alter table table_name add primary key (column_list);
  • 全文索引:
alter table table_name add fulltext index_name (column_list);

該語句指定了索引為 fulltext。

刪除索引

drop index index_name on table_name;
alter table table_name drop index index_name;
alter table table_name drop primary key; 

修改

  • MySQL 5.7以上:
alter table table_name rename index old_index_name to new_index_name;
  • MySQL 5.7之前:
alter table table_name drop index old_index_name
alter table table_name add index new_index_name(column_list)

查詢

使用 show index 命令來列出表中的相關(guān)的索引信息。

可以通過添加 \g 來格式化輸出信息。

show index from table_name \g

MySQL索引介紹及使用

MySQL索引介紹

1. 概念

MySQL官方對索引的定義為:索引(Index)是幫助MySQL高效獲取數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)??梢缘玫剿饕谋举|(zhì):索引是排好序的快速查找數(shù)據(jù)結(jié)構(gòu)。一般來說索引本身也很大,不可能全部存儲在內(nèi)存中,因此索引往往以索引文件的形式存儲在磁盤上。

2.優(yōu)勢

  • 所有的MySql列類型(字段類型)都可以被索引,也就是可以給任意字段設(shè)置索引。
  • 大大加快數(shù)據(jù)的查詢速度。       
  • 提高數(shù)據(jù)檢索的效率,降低數(shù)據(jù)排序的成本

3.劣勢

  • 實際上索引也是一張表,該表保存了主鍵與索引字段,并指向?qū)嶓w表的記錄,所以索引列也是要占用空間的。
  • 雖然索引大大提高了查詢速度,同時卻會降低更新表的速度,如對表進(jìn)行INSERT、UPDATE和DELETE。因為更新表時,MySQL不僅要保存數(shù)據(jù),還要保存一下索引文件每次更新添加了索引列的字段,都會調(diào)整因為更新所帶來的鍵值變化后的索引信息。
  • 索引只是提高效率的一個因素,如果你的MySQL有大數(shù)據(jù)量的表,就需要花時間研究建立最優(yōu)秀的索引,或者優(yōu)化查詢。

4.使用原則

  • 對經(jīng)常更新的表就避免對其設(shè)置過多的索引,對經(jīng)常用于查詢的字段應(yīng)該創(chuàng)建索引。
  • 數(shù)據(jù)量小的表最好不要使用索引,因為由于數(shù)據(jù)較少,可能查詢?nèi)繑?shù)據(jù)花費的時間比遍歷索引的時間還要短,索引就可能不會產(chǎn)生優(yōu)化效果。
  • 在一個列上(字段上)不同值較少的不要建立索引,比如在學(xué)生表的"性別"字段上只有男,女兩個不同值。相反的,在一個字段上不同值較多的可是建立索引。

5. mysql索引結(jié)構(gòu)

  • B+樹索引
  • Hash索引
  • full-text全文索引
  • R-Tree索引

6. 哪些情況需要創(chuàng)建索引

  • 主鍵自動建立唯一索引
  • 頻繁作為查詢條件的字段應(yīng)該創(chuàng)建索引
  • 查詢中與其它表關(guān)聯(lián)的字段,外鍵關(guān)系建立索引
  • 頻繁更新的字段不適合創(chuàng)建索引,因為每次更新不單單是更新了記錄,還會更新索引,加重IO負(fù)擔(dān)
  • where條件里用不到的字段不創(chuàng)建索引
  • 單鍵/組合索引的選擇問題,who?(在高并發(fā)下傾向創(chuàng)建組合索引)
  • 查詢中排序的字段,排序字段若通過索引去訪問將大大提高排序速度
  • 查詢中統(tǒng)計或者分組字段

7. 哪些情況不需要創(chuàng)建索引

  • 表記錄太少
  • 經(jīng)常增刪改的表:雖然提高了查詢速度,同時卻會降低更新表的速度,如對表進(jìn)行INSERT、UPDATE和DELETE。因為更新表時,MySQL不僅要保存數(shù)據(jù),還要保存一下索引文件。
  • 數(shù)據(jù)重復(fù)且分布平均的表字段,因此應(yīng)該只為最經(jīng)常查詢和最經(jīng)常排序的數(shù)據(jù)列建立索引。注意,如果某個數(shù)據(jù)列包含許多重復(fù)的內(nèi)容,為它建立索引就沒有太大的實際效果。

8. 創(chuàng)建索引的語句

CREATE TABLE table_name[col_name data type]
[unique|fulltext][index|key][index_name](col_name[length])[asc|desc]
  • unique|fulltext為可選參數(shù),分別表示唯一索引、全文索引
  • index和key為同義詞,兩者作用相同,用來指定創(chuàng)建索引
  • col_name為需要創(chuàng)建索引的字段列,該列必須從數(shù)據(jù)表中該定義的多個列中選擇
  • index_name指定索引的名稱,為可選參數(shù),如果不指定,默認(rèn)col_name為索引值
  • length為可選參數(shù),表示索引的長度,只有字符串類型的字段才能指定索引長度
  • asc或desc指定升序或降序的索引值存儲

9. 刪除索引的語句

DROP INDEX 索引名 ON 表名;
## 刪除book表中的名稱為BkNameIdx的索引
DROP INDEX BkNameIdx ON book;

10. 查看表的索引

## 查看表的索引
SHOW INDEX FROM book;

mysql索引分類及使用

MySQL中分為:普通索引,唯一索引,主鍵索引,組合索引,和全文索引。

1. 普通索引

是最基本的索引,它沒有任何限制,允許在定義索引的列中插入重復(fù)值和空值,純粹為了查詢數(shù)據(jù)更快一點。。

它有以下幾種創(chuàng)建方式:

# 1.直接創(chuàng)建索引
CREATE INDEX index_name ON table(column(length))
 
# 2.修改表結(jié)構(gòu)的方式添加索引
ALTER TABLE table_name ADD INDEX index_name ON (column(length))
 
# 3.創(chuàng)建表的時候同時創(chuàng)建索引
CREATE TABLE `table` (
    `id` int(11) NOT NULL AUTO_INCREMENT ,
    `title` char(255) CHARACTER NOT NULL ,
    `content` text CHARACTER NULL ,
    `time` int(10) NULL DEFAULT NULL ,
    PRIMARY KEY (`id`),
    INDEX index_name (title(length))
)
 
# 4.刪除索引
DROP INDEX index_name ON table

2. 唯一索引

與前面的普通索引類似,不同的就是:索引列的值必須唯一,但允許有空值。如果是組合索引,則列值的組合必須唯一。

它有以下幾種創(chuàng)建方式:

# 1.創(chuàng)建唯一索引
CREATE UNIQUE INDEX indexName ON table(column(length))
 
# 2.修改表結(jié)構(gòu)
ALTER TABLE table_name ADD UNIQUE indexName ON (column(length))
 
# 3.創(chuàng)建表的時候直接指定
CREATE TABLE `table` (
    `id` int(11) NOT NULL AUTO_INCREMENT ,
    `title` char(255) CHARACTER NOT NULL ,
    `content` text CHARACTER NULL ,
    `time` int(10) NULL DEFAULT NULL ,
     UNIQUE indexName (title(length))
);

3. 主鍵索引

是一種特殊的唯一索引,一個表只能有一個主鍵,不允許有空值。

一般是在建表的時候同時創(chuàng)建主鍵索引:

CREATE TABLE `table` (
    `id` int(11) NOT NULL AUTO_INCREMENT ,
    `title` char(255) NOT NULL ,
     PRIMARY KEY (`id`)
);

4. 組合索引

指多個字段上創(chuàng)建的索引,只有在查詢條件中使用了創(chuàng)建索引時的第一個字段,索引才會被使用。

使用組合索引時遵循最左前綴集合

#添加組合索引
ALTER TABLE `table` ADD INDEX name_city_age (id,name,age); 
 
#創(chuàng)建組合索引
CREATE TABLE tab3(
id INT(4) NOT NULL,
name CHAR(20) NOT NULL,
age INT(3) NOT NULL,
info VARCHAR(255),
INDEX multiIdx(id,name,age)
);

最左前綴:組合索引遵從了最左前綴,利用索引中最左邊的列集來匹配行,這樣的列集稱為最左前綴。例如,這里由id、name和age3個字段構(gòu)成的索引,索引行中就按id/name/age的順序存放,索引組合中的字段可以是(id,name,age)、(id,name)或者(id)。如果要查詢的字段不構(gòu)成最左面的前綴原則,那么就不會用索引,比如,age或者(name,age)組合就不會使用索引查詢。

5. 全文索引

主要用來查找文本中的關(guān)鍵字,而不是直接與索引中的值相比較。

fulltext索引跟其它索引大不相同,它更像是一個搜索引擎,而不是簡單的where語句的參數(shù)匹配。

fulltext索引配合match against操作使用,而不是一般的where語句加like。

它可以在create table,alter table ,create index使用,不過目前只有char、varchar,text 列上可以創(chuàng)建全文索引。

值得一提的是,在數(shù)據(jù)量較大時候,現(xiàn)將數(shù)據(jù)放入一個沒有全局索引的表中,然后再用CREATE index創(chuàng)建fulltext索引,要比先為一張表建立fulltext然后再將數(shù)據(jù)寫入的速度快很多。

# 1.創(chuàng)建表的適合添加全文索引
CREATE TABLE `table` (
    `id` int(11) NOT NULL AUTO_INCREMENT ,
    `title` char(255) CHARACTER NOT NULL ,
    `content` text CHARACTER NULL ,
    `time` int(10) NULL DEFAULT NULL ,
    PRIMARY KEY (`id`),
    FULLTEXT (content)
);
 
# 2.修改表結(jié)構(gòu)添加全文索引
ALTER TABLE article ADD FULLTEXT index_content(content)
 
# 3.直接創(chuàng)建索引
CREATE FULLTEXT INDEX index_content ON article(content)

Explain

1. 概念

Explain(查看執(zhí)行計劃),使用EXPLAIN關(guān)鍵字可以模擬優(yōu)化器執(zhí)行SQL查詢語句,從而知道MySQL是如何處理你的SQL語句的。

分析你的查詢語句或是表結(jié)構(gòu)的性能瓶頸。

2. 功能

  • 表的讀取順序
  • 數(shù)據(jù)讀取操作的操作類型
  • 哪些索引可以使用
  • 哪些索引被實際使用
  • 表之間的應(yīng)用
  • 每張表有多少行被優(yōu)化器查詢

3. 使用方法

Explain+SQL語句,例如

# 創(chuàng)建唯一索引
CREATE TABLE tab1(
id INT(5) NOT NULL,
name CHAR(20) NOT NULL,
UNIQUE INDEX uniqId(id)
);
 
# 查看索引使用信息
EXPLAIN SELECT * FROM tab1 WHERE id = 1;

4.執(zhí)行計劃包含的信息

id: select查詢的序列號,包含一組數(shù)字,表示查詢中執(zhí)行select子句或操作表的順序

  • id相同,執(zhí)行順序由上至下
  • id不同,如果是子查詢,id的序號會遞增,id值越大優(yōu)先級越高,越先被執(zhí)行
  • id相同不同,同時存在

select_type:查詢的類型,主要是用于區(qū)別普通查詢、聯(lián)合查詢、子查詢等的復(fù)雜查詢

  • SIMPLE:簡單的select查詢,查詢中不包含子查詢或者UNION。
  • PRIMARY:查詢中包含任何復(fù)雜的子部分,最外層查詢則被標(biāo)記為PRIMARY。
  • SUBQUERY:在FROM列表中包含的子查詢被標(biāo)記為DERIVED(衍生),MySQL會遞歸執(zhí)行這些子查詢,把結(jié)果放在臨時表里。
  • DERIVED:在FROM列表中包含的子查詢被標(biāo)記為DERIVED(衍生)。MySQL會遞歸執(zhí)行這些子查詢,把結(jié)果放在臨時表里。
  • UNION:若第二個SELECT出現(xiàn)在UNION之后,則被標(biāo)記為UNION;若UNION包含在FROM子句的子查詢中,外層SELECT將被標(biāo)記為:DERIVED。
  • UNION RESULT:從UNION表中獲取結(jié)果的SELECT。

table:顯示這一行的數(shù)據(jù)是關(guān)于哪些表的。

type顯示的是訪問類型,是較為重要的一個指標(biāo)

結(jié)果值從最好到最壞依次是:system>const>eq_ref>ref>range>index>All

  • system:表只有一行記錄(等于系統(tǒng)表),這是const類型的特例,平時不會出現(xiàn),這個也可以忽略不計。
  • const:表示通過索引一次就找到了,const用于比較primary key或則unique索引。因為只匹配一行數(shù)據(jù),所以很快。如將主鍵置于where列表中,MySQL就能將該查詢轉(zhuǎn)換為一個常量。
  • eq_ref:唯一性索引掃描,對于每個索引鍵,表中只有一條記錄與之匹配。常見于主鍵或唯一索引掃描。
  • ref:非唯一性索引掃描,返回匹配某個單獨值的所有行。本質(zhì)上也是一種索引訪問,它返回所有匹配某個單獨值的行,然而,它可能會找到多個符合條件的行,所以它應(yīng)該屬于查找和掃描的混合體。
  • range:只檢索給定范圍的行,使用一個索引來選擇行。key列顯示使用了哪個索引。一般就是在你的where語句中出現(xiàn)了between、<、>、in等的查詢。這種范圍掃描索引掃描比全表掃描要好,因為它只需要開始于索引的某一點,而結(jié)束于另一點,不會掃描全部索引。
  • index:Full Index Scan,index與All區(qū)別為index類型只遍歷索引樹。這通常比All快,因為索引文件通常比數(shù)據(jù)文件小。(也就是說雖然all和index都是讀全表,但index是從索引中讀取的,而all是從硬盤中讀的)
  • all:Full Table Scan,將遍歷全表以找到匹配的行。

一般來說,得保證查詢至少達(dá)到range級別,最好能達(dá)到ref。

possible_keys:顯示可能應(yīng)用在這張表中的索引,一個或多個。查詢涉及到的字段上若存在索引,則該索引將被列出。但不一定被查詢實際使用。

key:實際使用的索引。如果為NULL,則沒有使用索引。查詢中若使用了覆蓋索引,則該索引僅出現(xiàn)在key列表中,不會出現(xiàn)在possible_keys列表中。(覆蓋索引:查詢的字段與建立的復(fù)合索引的個數(shù)一一吻合)

key_len:表示索引中使用的字節(jié)數(shù),可通過該列計算查詢中使用的索引的長度。在不損失精確性的情況下,長度越短越好。key_len顯示的值為索引字段的最大可能長度,并非實際使用長度,即key_len是根據(jù)表定義計算而得,不是通過表內(nèi)檢索出的。

ref:顯示索引的哪一列被使用了,如果可能的話,是一個常數(shù)。哪些列或常量被用于查找索引列上的值。查詢中與其它表關(guān)聯(lián)的字段,外鍵關(guān)系建立索引。

rows:根據(jù)表統(tǒng)計信息及索引選用情況,大致估算出找到所需的記錄所需要讀取的行數(shù)。

Extra:包含不適合在其他列中顯示但十分重要的額外信息。

  • Using filesort:說明mysql會對數(shù)據(jù)使用一個外部的索引排序,而不是按照表內(nèi)的索引順序進(jìn)行讀取。MySQL中無法利用索引完成的排序操作成為“文件排序”。
  • Using temporary:使用了臨時表保存中間結(jié)果,MySQL在對查詢結(jié)果排序時使用臨時表。常見于排序order by和分組查詢group by。
  • Using index:表示相應(yīng)的select操作中使用了覆蓋索引(Covering Index),避免訪問了表的數(shù)據(jù)行,效率不錯!如果同時出現(xiàn)using where,表明索引被用來執(zhí)行索引鍵值的查找;如果沒有同時出現(xiàn)using where,表明索引用來讀取數(shù)據(jù)而非執(zhí)行查找動作。
  • Using where:表明使用了where過濾。
  • Using join buffer:使用了連接緩存。
  • impossible where:where子句的值總是false,不能用來獲取任何元組。(查詢語句中where的條件不可能被滿足,恒為False)
  • select tables optimized away:在沒有GROUPBY子句的情況下,基于索引優(yōu)化MIN/MAX操作或者對于MyISAM存儲引擎優(yōu)化COUNT(*)操作,不必等到執(zhí)行階段再進(jìn)行計算,查詢執(zhí)行計劃生成的階段即完成優(yōu)化。
  • distinct:優(yōu)化distinct操作,在找到第一匹配的元組后即停止找相同值的動作。

單表索引優(yōu)化案例分析

#創(chuàng)建表的SQL語句
CREATE TABLE article(
	id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
	author_id INT(10) UNSIGNED NOT NULL,
	category_id INT(10) UNSIGNED NOT NULL,
	views INT(10) UNSIGNED NOT NULL,
	comments INT(10) UNSIGNED NOT NULL,
	title VARBINARY(255) NOT NULL,
	content TEXT NOT NULL
);
 
INSERT INTO article(author_id,category_id,views,comments,title,content) 
VALUES(1,1,1,1,'1','1'),(2,2,2,2,'2','2'),(3,3,3,3,'3','3');

在沒有創(chuàng)建索引的時候,使用explain查看執(zhí)行計劃

# 查詢category_id=1 且comments>1的情況下,views最多的article_id
EXPLAIN 
SELECT id,author_id 
FROM article 
WHERE category_id=1 
AND comments>1 
ORDER BY views DESC 
LIMIT 1;

結(jié)論:type是ALL,最壞的情況,extra中出現(xiàn)了using filesort,也是最壞的情況,必須進(jìn)行優(yōu)化

#開始優(yōu)化
#創(chuàng)建索引
#alter table article add index idx_article_ccv(category_id,comments,views);
CREATE INDEX idx_article_ccv ON article(category_id,comments,views);
 
#第二次explain
EXPLAIN 
SELECT id,author_id 
FROM article 
WHERE category_id=1 
AND comments>1 
ORDER BY views DESC 
LIMIT 1;

type變成了range,這是可以忍受的,但是extra里using filesort是無法接受的。

但是已經(jīng)創(chuàng)建了索引,為什么沒有用?因為按照Btree索引的工作原理,先降序category_id,如果遇到相同的category_id,再排序comments,如果遇到相同的comments,再排序views。

當(dāng)comments字段在聯(lián)合索引中處于中間位置時,因comments>1條件是一個范圍值,故MySQL無法利用索引再對后面的views部分進(jìn)行檢索,即range類型查詢字段后面的索引無效。

#刪除第一次創(chuàng)建的索引
DROP INDEX idx_article_ccv ON article;
 
#第2次新建索引
CREATE INDEX idx_article_cv ON article(category_id,views);
 
#第3次explain
EXPLAIN 
SELECT id,author_id 
FROM article 
WHERE category_id=1 
AND comments>1 
ORDER BY views DESC 
LIMIT 1;

結(jié)論:type變成ref,extra中的using filesort也消失了,結(jié)果非常理想。

索引失效

以具體的案例說明失效的情況,首先先創(chuàng)建員工表和索引:

#創(chuàng)建員工表
CREATE TABLE staffs(
	id INT PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAR(24) NOT NULL DEFAULT "" COMMENT '姓名',
	age INT NOT NULL DEFAULT 0 COMMENT '年齡',
	pos VARCHAR(20) NOT NULL DEFAULT "" COMMENT '職位',
	add_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT'入職時間'
) CHARSET utf8 COMMENT '員工記錄表';
 
INSERT INTO staffs(NAME,age,pos,add_time) VALUES('z3',22,'manager',NOW()),('july',23,'dev',NOW()),('2000',23,'dev',NOW());
 
 
#創(chuàng)建索引
ALTER TABLE staffs ADD INDEX idx_staffs_nameAgePos(NAME,age,pos);

1.聯(lián)合索引(符合索引)不使用第一部分

創(chuàng)建聯(lián)合索引,但是沒有遵循最左前綴法則,則會出現(xiàn)索引失效的情況。

如果索引了多列,要遵守最左前綴法則。

指的是查詢從索引的最左前列開始并且不跳過索引中的列。(帶頭大哥不能死,中間兄弟不能斷哈哈哈)

2.where條件有數(shù)學(xué)運算或函數(shù)

3.mysql在使用不等于(!=或者<>)的時候無法使用索引會導(dǎo)致全表掃描

4. mysql在使用 is null,is not null也無法使用索引

5. like以通配符開頭(‘%abc…’)mysql索引失效會變成全表掃描的操作,當(dāng)%加在右邊時可以使用

6. 字符串不加單引號索引失效

7. where條件使用or

注意:要想使用or,又想讓索引生效,只能將or條件中的每個列都加上索引

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論