Mysql創(chuàng)建索引

1.索引作用

在索引列上蜒简,除了上面提到的有序查找之外瘸羡,數(shù)據(jù)庫利用各種各樣的快速定位技術(shù),能夠大大提高查詢效率搓茬。特別是當(dāng)數(shù)據(jù)量非常大犹赖,查詢涉及多個(gè)表時(shí),使用索引往往能使查詢速度加快成千上萬倍卷仑。

例如峻村,有3個(gè)未索引的表t1、t2系枪、t3雀哨,分別只包含列c1磕谅、c2私爷、c3,每個(gè)表分別含有1000行數(shù)據(jù)組成膊夹,指為1~1000的數(shù)值衬浑,查找對應(yīng)值相等行的查詢?nèi)缦滤尽?/p>


SELECT c1,c2,c3 FROM t1,t2,t3 WHERE c1=c2 AND c1=c3

此查詢結(jié)果應(yīng)該為1000行,每行包含3個(gè)相等的值放刨。在無索引的情況下處理此查詢工秩,必須尋找3個(gè)表所有的組合,以便得出與WHERE子句相配的那些行进统。而可能的組合數(shù)目為1000×1000×1000(十億)助币,顯然查詢將會非常慢。

如果對每個(gè)表進(jìn)行索引螟碎,就能極大地加速查詢進(jìn)程眉菱。利用索引的查詢處理如下。

(1)從表t1中選擇第一行掉分,查看此行所包含的數(shù)據(jù)俭缓。

(2)使用表t2上的索引,直接定位t2中與t1的值匹配的行酥郭。類似华坦,利用表t3上的索引,直接定位t3中與來自t1的值匹配的行不从。

(3)掃描表t1的下一行并重復(fù)前面的過程惜姐,直到遍歷t1中所有的行。

在此情形下椿息,仍然對表t1執(zhí)行了一個(gè)完全掃描载弄,但能夠在表t2和t3上進(jìn)行索引查找直接取出這些表中的行耘拇,比未用索引時(shí)要快一百萬倍。

利用索引宇攻,MySQL加速了WHERE子句滿足條件行的搜索惫叛,而在多表連接查詢時(shí),在執(zhí)行連接時(shí)加快了與其他表中的行匹配的速度逞刷。

2.創(chuàng)建索引

在執(zhí)行CREATE TABLE語句時(shí)可以創(chuàng)建索引嘉涌,也可以單獨(dú)用CREATE INDEX或ALTER TABLE來為表增加索引。

1.ALTER TABLE

ALTER TABLE用來創(chuàng)建普通索引夸浅、UNIQUE索引或PRIMARY KEY索引仑最。


ALTER TABLE table_name ADD INDEX index_name (column_list)

ALTER TABLE table_name ADD UNIQUE (column_list)

ALTER TABLE table_name ADD PRIMARY KEY (column_list)


其中table_name是要增加索引的表名,column_list指出對哪些列進(jìn)行索引帆喇,多列時(shí)各列之間用逗號分隔警医。索引名index_name可選,缺省時(shí)坯钦,MySQL將根據(jù)第一個(gè)索引列賦一個(gè)名稱预皇。另外,ALTER TABLE允許在單個(gè)語句中更改多個(gè)表婉刀,因此可以在同時(shí)創(chuàng)建多個(gè)索引吟温。

2.CREATE INDEX

CREATE INDEX可對表增加普通索引或UNIQUE索引。


CREATE INDEX index_name ON table_name (column_list)

CREATE UNIQUE INDEX index_name ON table_name (column_list)


table_name突颊、index_name和column_list具有與ALTER TABLE語句中相同的含義鲁豪,索引名不可選。另外律秃,不能用CREATE INDEX語句創(chuàng)建PRIMARY KEY索引爬橡。

3.索引類型

在創(chuàng)建索引時(shí),可以規(guī)定索引能否包含重復(fù)值棒动。如果不包含糙申,則索引應(yīng)該創(chuàng)建為PRIMARY KEY或UNIQUE索引。對于單列惟一性索引迁客,這保證單列不包含重復(fù)的值郭宝。對于多列惟一性索引,保證多個(gè)值的組合不重復(fù)掷漱。

PRIMARY KEY索引和UNIQUE索引非常類似粘室。事實(shí)上,PRIMARY KEY索引僅是一個(gè)具有名稱PRIMARY的UNIQUE索引卜范。這表示一個(gè)表只能包含一個(gè)PRIMARY KEY衔统,因?yàn)橐粋€(gè)表中不可能具有兩個(gè)同名的索引。

下面的SQL語句對students表在sid上添加PRIMARY KEY索引。


ALTER TABLE students ADD PRIMARY KEY (sid)


4.刪除索引

可利用ALTER TABLE或DROP INDEX語句來刪除索引锦爵。類似于CREATE INDEX語句舱殿,DROP INDEX可以在ALTER TABLE內(nèi)部作為一條語句處理,語法如下险掀。


DROP INDEX index_name ON talbe_name

ALTER TABLE table_name DROP INDEX index_name

ALTER TABLE table_name DROP PRIMARY KEY


其中沪袭,前兩條語句是等價(jià)的,刪除掉table_name中的索引index_name樟氢。

第3條語句只在刪除PRIMARY KEY索引時(shí)使用冈绊,因?yàn)橐粋€(gè)表只可能有一個(gè)PRIMARY KEY索引,因此不需要指定索引名埠啃。如果沒有創(chuàng)建PRIMARY KEY索引死宣,但表具有一個(gè)或多個(gè)UNIQUE索引,則MySQL將刪除第一個(gè)UNIQUE索引碴开。

如果從表中刪除了某列毅该,則索引會受到影響。對于多列組合的索引潦牛,如果刪除其中的某列眶掌,則該列也會從索引中刪除。如果刪除組成索引的所有列罢绽,則整個(gè)索引將被刪除畏线。


5.查看索引

mysql> show?index from tblname;

mysql> show keys from tblname;

· Table

表的名稱静盅。

· Non_unique

如果索引不能包括重復(fù)詞良价,則為0。如果可以蒿叠,則為1明垢。

· Key_name

索引的名稱。

· Seq_in_index

索引中的列序列號市咽,從1開始痊银。

· Column_name

列名稱。

· Collation

列以什么方式存儲在索引中施绎。在MySQL中溯革,有值‘A’(升序)或NULL(無分類)。

· Cardinality

索引中唯一值的數(shù)目的估計(jì)值谷醉。通過運(yùn)行ANALYZE TABLE或myisamchk -a可以更新致稀。基數(shù)根據(jù)被存儲為整數(shù)的統(tǒng)計(jì)數(shù)據(jù)來計(jì)數(shù)俱尼,所以即使對于小型表抖单,該值也沒有必要是精確的。基數(shù)越大矛绘,當(dāng)進(jìn)行聯(lián)合時(shí)耍休,MySQL使用該索引的機(jī)會就越大。

· Sub_part

如果列只是被部分地編入索引货矮,則為被編入索引的字符的數(shù)目羊精。如果整列被編入索引,則為NULL囚玫。

· Packed

指示關(guān)鍵字如何被壓縮园匹。如果沒有被壓縮,則為NULL劫灶。

· Null

如果列含有NULL裸违,則含有YES。如果沒有本昏,則該列含有NO供汛。

· Index_type

用過的索引方法(BTREE, FULLTEXT, HASH, RTREE)。

· Comment

6.什么情況下使用索引

?????? 表的主關(guān)鍵字

自動(dòng)建立唯一索引

如zl_yhjbqk(用戶基本情況)中的hbs_bh(戶標(biāo)識編號)

表的字段唯一約束

ORACLE利用索引來保證數(shù)據(jù)的完整性

如lc_hj(流程環(huán)節(jié))中的lc_bh+hj_sx(流程編號+環(huán)節(jié)順序)

直接條件查詢的字段

在SQL中用于條件約束的字段

如zl_yhjbqk(用戶基本情況)中的qc_bh(區(qū)冊編號)

select * from zl_yhjbqk where qc_bh=’7001’

查詢中與其它表關(guān)聯(lián)的字段

字段常常建立了外鍵關(guān)系

如zl_ydcf(用電成份)中的jldb_bh(計(jì)量點(diǎn)表編號)

select * from zl_ydcf a,zl_yhdb b where a.jldb_bh=b.jldb_bh and b.jldb_bh=’540100214511’

查詢中排序的字段

排序的字段如果通過索引去訪問那將大大提高排序速度

select * from zl_yhjbqk order by qc_bh(建立qc_bh索引)

select * from zl_yhjbqk where qc_bh=’7001’ order by cb_sx(建立qc_bh+cb_sx索引涌穆,注:只是一個(gè)索引怔昨,其中包括qc_bh和cb_sx字段)

查詢中統(tǒng)計(jì)或分組統(tǒng)計(jì)的字段

select max(hbs_bh) from zl_yhjbqk

select qc_bh,count(*) from zl_yhjbqk group by qc_bh

什么情況下應(yīng)不建或少建索引

表記錄太少

如果一個(gè)表只有5條記錄,采用索引去訪問記錄的話宿稀,那首先需訪問索引表趁舀,再通過索引表訪問數(shù)據(jù)表,一般索引表與數(shù)據(jù)表不在同一個(gè)數(shù)據(jù)塊祝沸,這種情況下ORACLE至少要往返讀取數(shù)據(jù)塊兩次矮烹。而不用索引的情況下ORACLE會將所有的數(shù)據(jù)一次讀出,處理速度顯然會比用索引快罩锐。

如表zl_sybm(使用部門)一般只有幾條記錄奉狈,除了主關(guān)鍵字外對任何一個(gè)字段建索引都不會產(chǎn)生性能優(yōu)化,實(shí)際上如果對這個(gè)表進(jìn)行了統(tǒng)計(jì)分析后ORACLE也不會用你建的索引涩惑,而是自動(dòng)執(zhí)行全表訪問仁期。如:

select * from zl_sybm where sydw_bh=’5401’(對sydw_bh建立索引不會產(chǎn)生性能優(yōu)化)

經(jīng)常插入、刪除竭恬、修改的表

對一些經(jīng)常處理的業(yè)務(wù)表應(yīng)在查詢允許的情況下盡量減少索引跛蛋,如zl_yhbm,gc_dfss痊硕,gc_dfys赊级,gc_fpdy等業(yè)務(wù)表。

數(shù)據(jù)重復(fù)且分布平均的表字段

假如一個(gè)表有10萬行記錄寿桨,有一個(gè)字段A只有T和F兩種值此衅,且每個(gè)值的分布概率大約為50%强戴,那么對這種表A字段建索引一般不會提高數(shù)據(jù)庫的查詢速度。

經(jīng)常和主字段一塊查詢但主字段索引值比較多的表字段

如gc_dfss(電費(fèi)實(shí)收)表經(jīng)常按收費(fèi)序號挡鞍、戶標(biāo)識編號骑歹、抄表日期、電費(fèi)發(fā)生年月墨微、操作 標(biāo)志來具體查詢某一筆收款的情況道媚,如果將所有的字段都建在一個(gè)索引里那將會增加數(shù)據(jù)的修改、插入翘县、刪除時(shí)間最域,從實(shí)際上分析一筆收款如果按收費(fèi)序號索引就已 經(jīng)將記錄減少到只有幾條,如果再按后面的幾個(gè)字段索引查詢將對性能不產(chǎn)生太大的影響锈麸。

對千萬級MySQL數(shù)據(jù)庫建立索引的事項(xiàng)及提高性能的手段

一镀脂、注意事項(xiàng):

首先,應(yīng)當(dāng)考慮表空間和磁盤空間是否足夠忘伞。我們知道索引也是一種數(shù)據(jù)薄翅,在建立索引的時(shí)候勢必也會占用大量表空間。因此在對一大表建立索引的時(shí)候首先應(yīng)當(dāng)考慮的是空間容量問題氓奈。

其次翘魄,在對建立索引的時(shí)候要對表進(jìn)行加鎖,因此應(yīng)當(dāng)注意操作在業(yè)務(wù)空閑的時(shí)候進(jìn)行舀奶。

二暑竟、性能調(diào)整方面:

首當(dāng)其沖的考慮因素便是磁盤I/O。物理上育勺,應(yīng)當(dāng)盡量把索引與數(shù)據(jù)分散到不同的磁盤上(不考慮陣列的情況)但荤。邏輯上,數(shù)據(jù)表空間與索引表空間分開怀大。這是在建索引時(shí)應(yīng)當(dāng)遵守的基本準(zhǔn)則纱兑。

其次呀闻,我們知道化借,在建立索引的時(shí)候要對表進(jìn)行全表的掃描工作,因此捡多,應(yīng)當(dāng)考慮調(diào)大初始化參數(shù)db_file_multiblock_read_count的值蓖康。一般設(shè)置為32或更大。

再次垒手,建立索引除了要進(jìn)行全表掃描外同時(shí)還要對數(shù)據(jù)進(jìn)行大量的排序操作蒜焊,因此,應(yīng)當(dāng)調(diào)整排序區(qū)的大小科贬。

????9i之前泳梆,可以在session級別上加大sort_area_size的大小鳖悠,比如設(shè)置為100m或者更大。

????9i以后优妙,如果初始化參數(shù)workarea_size_policy的值為TRUE乘综,則排序區(qū)從pga_aggregate_target里自動(dòng)分配獲得。

最后套硼,建立索引的時(shí)候卡辰,可以加上nologging選項(xiàng)。以減少在建立索引過程中產(chǎn)生的大量redo邪意,從而提高執(zhí)行的速度九妈。

MySql在建立索引優(yōu)化時(shí)需要注意的問題

設(shè)計(jì)好MySql的索引可以讓你的數(shù)據(jù)庫飛起來,大大的提高數(shù)據(jù)庫效率雾鬼。設(shè)計(jì)MySql索引的時(shí)候有一下幾點(diǎn)注意:

1萌朱,創(chuàng)建索引

對于查詢占主要的應(yīng)用來說,索引顯得尤為重要策菜。很多時(shí)候性能問題很簡單的就是因?yàn)槲覀兺颂砑铀饕斐傻娜峦茫蛘哒f沒有添加更為有效的索引導(dǎo)致。如果不加

索引的話做入,那么查找任何哪怕只是一條特定的數(shù)據(jù)都會進(jìn)行一次全表掃描冒晰,如果一張表的數(shù)據(jù)量很大而符合條件的結(jié)果又很少,那么不加索引會引起致命的性能下

降竟块。但是也不是什么情況都非得建索引不可壶运,比如性別可能就只有兩個(gè)值,建索引不僅沒什么優(yōu)勢浪秘,還會影響到更新速度蒋情,這被稱為過度索引。

2耸携,復(fù)合索引

比如有一條語句是這樣的:select * from users where area=’beijing’ and age=22;

如果我們是在area和age上分別創(chuàng)建單個(gè)索引的話棵癣,由于mysql查詢每次只能使用一個(gè)索引,所以雖然這樣已經(jīng)相對不做索引時(shí)全表掃描提高了很多效

率夺衍,但是如果在area狈谊、age兩列上創(chuàng)建復(fù)合索引的話將帶來更高的效率。如果我們創(chuàng)建了(area, age,

salary)的復(fù)合索引沟沙,那么其實(shí)相當(dāng)于創(chuàng)建了(area,age,salary)河劝、(area,age)、(area)三個(gè)索引矛紫,這被稱為最佳左前綴

特性赎瞎。因此我們在創(chuàng)建復(fù)合索引時(shí)應(yīng)該將最常用作限制條件的列放在最左邊,依次遞減颊咬。

3务甥,索引不會包含有NULL值的列

只要列中包含有NULL值都將不會被包含在索引中牡辽,復(fù)合索引中只要有一列含有NULL值,那么這一列對于此復(fù)合索引就是無效的敞临。所以我們在數(shù)據(jù)庫設(shè)計(jì)時(shí)不要讓字段的默認(rèn)值為NULL催享。

4,使用短索引

對串列進(jìn)行索引哟绊,如果可能應(yīng)該指定一個(gè)前綴長度因妙。例如,如果有一個(gè)CHAR(255)的 列票髓,如果在前10 個(gè)或20 個(gè)字符內(nèi)攀涵,多數(shù)值是惟一的,那么就不要對整個(gè)列進(jìn)行索引洽沟。短索引不僅可以提高查詢速度而且可以節(jié)省磁盤空間和I/O操作以故。

5,排序的索引問題

mysql查詢只使用一個(gè)索引裆操,因此如果where子句中已經(jīng)使用了索引的話怒详,那么order by中的列是不會使用索引的。因此數(shù)據(jù)庫默認(rèn)排序可以符合要求的情況下不要使用排序操作踪区;盡量不要包含多個(gè)列的排序昆烁,如果需要最好給這些列創(chuàng)建復(fù)合索引。

6缎岗,like語句操作

一般情況下不鼓勵(lì)使用like操作静尼,如果非使用不可,如何使用也是一個(gè)問題传泊。like “%aaa%” 不會使用索引而like “aaa%”可以使用索引鼠渺。

7,不要在列上進(jìn)行運(yùn)算

select * from users where

YEAR(adddate)

8拦盹,不使用NOT IN和操作

NOT IN和操作都不會使用索引將進(jìn)行全表掃描。NOT IN可以NOT EXISTS代替溪椎,id3則可使用id>3 or id

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末普舆,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子池磁,更是在濱河造成了極大的恐慌奔害,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件地熄,死亡現(xiàn)場離奇詭異,居然都是意外死亡芯杀,警方通過查閱死者的電腦和手機(jī)端考,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進(jìn)店門雅潭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人却特,你說我怎么就攤上這事扶供。” “怎么了裂明?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵椿浓,是天一觀的道長。 經(jīng)常有香客問我闽晦,道長扳碍,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任仙蛉,我火速辦了婚禮笋敞,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘荠瘪。我一直安慰自己夯巷,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布哀墓。 她就那樣靜靜地躺著趁餐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪篮绰。 梳的紋絲不亂的頭發(fā)上澎怒,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天,我揣著相機(jī)與錄音阶牍,去河邊找鬼喷面。 笑死,一個(gè)胖子當(dāng)著我的面吹牛走孽,可吹牛的內(nèi)容都是我干的惧辈。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼磕瓷,長吁一口氣:“原來是場噩夢啊……” “哼盒齿!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起困食,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤边翁,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后硕盹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體符匾,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年瘩例,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了啊胶。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片甸各。...
    茶點(diǎn)故事閱讀 39,727評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖焰坪,靈堂內(nèi)的尸體忽然破棺而出趣倾,到底是詐尸還是另有隱情,我是刑警寧澤某饰,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布儒恋,位于F島的核電站,受9級特大地震影響黔漂,放射性物質(zhì)發(fā)生泄漏诫尽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一瘟仿、第九天 我趴在偏房一處隱蔽的房頂上張望箱锐。 院中可真熱鬧,春花似錦劳较、人聲如沸驹止。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽臊恋。三九已至,卻和暖如春墓捻,著一層夾襖步出監(jiān)牢的瞬間抖仅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工砖第, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留撤卢,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓梧兼,卻偏偏與公主長得像放吩,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子羽杰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內(nèi)容