国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數(shù)據(jù)庫 > MySQL > 正文

mysql索引的建立和使用

2024-07-24 12:59:26
字體:
供稿:網(wǎng)友

一、索引的概念        索引就是加快檢索表中數(shù)據(jù)的方法。數(shù)據(jù)庫的索引類似于書籍的索引。在書籍中,索引允許用戶不必翻閱完整個(gè)書就能迅速地找到所需要的信息。在數(shù)據(jù)庫中,索引也允許數(shù)據(jù)庫程序迅速地找到表中的數(shù)據(jù),而不必掃描整個(gè)數(shù)據(jù)庫。

二、索引的特點(diǎn)    1.索引可以加快數(shù)據(jù)庫的檢索速度     2.索引降低了數(shù)據(jù)庫插入、修改、刪除等維護(hù)任務(wù)的速度     3.索引創(chuàng)建在表上,不能創(chuàng)建在視圖上     4.索引既可以直接創(chuàng)建,也可以間接創(chuàng)建     5.可以在優(yōu)化隱藏中,使用索引     6.使用查詢處理器執(zhí)行SQL語句,在一個(gè)表上,一次只能使用一個(gè)索引     7.其他

三、索引的優(yōu)點(diǎn)    1.創(chuàng)建唯一性索引,保證數(shù)據(jù)庫表中每一行數(shù)據(jù)的唯一性    2.大大加快數(shù)據(jù)的檢索速度,這也是創(chuàng)建索引的最主要的原因    3.加速表和表之間的連接,特別是在實(shí)現(xiàn)數(shù)據(jù)的參考完整性方面特別有意義。    4.在使用分組和排序子句進(jìn)行數(shù)據(jù)檢索時(shí),同樣可以顯著減少查詢中分組和排序的時(shí)間。    5.通過使用索引,可以在查詢的過程中使用優(yōu)化隱藏器,提高系統(tǒng)的性能。

四、索引的缺點(diǎn)    1.創(chuàng)建索引和維護(hù)索引要耗費(fèi)時(shí)間,這種時(shí)間隨著數(shù)據(jù)量的增加而增加    2.索引需要占物理空間,除了數(shù)據(jù)表占數(shù)據(jù)空間之外,每一個(gè)索引還要占一定的物理空間,如果要建立聚簇索引,那么需要的空間就會(huì)更大    3.當(dāng)對(duì)表中的數(shù)據(jù)進(jìn)行增加、刪除和修改的時(shí)候,索引也要?jiǎng)討B(tài)的維護(hù),降低了數(shù)據(jù)的維護(hù)速度

五、索引分類    1.直接創(chuàng)建索引和間接創(chuàng)建索引    直接創(chuàng)建索引: CREATE INDEX mycolumn_index ON mytable (myclumn)    間接創(chuàng)建索引:定義主鍵約束或者唯一性鍵約束,可以間接創(chuàng)建索引    2.普通索引和唯一性索引    普通索引:CREATE INDEX mycolumn_index ON mytable (myclumn)    唯一性索引:保證在索引列中的全部數(shù)據(jù)是唯一的,對(duì)聚簇索引和非聚簇索引都可以使用    CREATE UNIQUE COUSTERED INDEX myclumn_cindex ON mytable(mycolumn)    3.單個(gè)索引和復(fù)合索引    單個(gè)索引:即非復(fù)合索引    復(fù)合索引:又叫組合索引,在索引建立語句中同時(shí)包含多個(gè)字段名,最多16個(gè)字段    CREATE INDEX name_index ON username(firstname,lastname)    4.聚簇索引和非聚簇索引(聚集索引,群集索引)   聚簇索引:物理索引,與基表的物理順序相同,數(shù)據(jù)值的順序總是按照順序排列    CREATE CLUSTERED INDEX mycolumn_cindex ON mytable(mycolumn) WITH    ALLOW_DUP_ROW(允許有重復(fù)記錄的聚簇索引)   非聚簇索引:CREATE UNCLUSTERED INDEX mycolumn_cindex ON mytable(mycolumn)

六、索引的使用   1.當(dāng)字段數(shù)據(jù)更新頻率較低,查詢使用頻率較高并且存在大量重復(fù)值是建議使用聚簇索引    2.經(jīng)常同時(shí)存取多列,且每列都含有重復(fù)值可考慮建立組合索引    3.復(fù)合索引的前導(dǎo)列一定好控制好,否則無法起到索引的效果。如果查詢時(shí)前導(dǎo)列不在查詢條件中則該復(fù)合索引不會(huì)被使用。前導(dǎo)列一定是使用最頻繁的列    4.多表操作在被實(shí)際執(zhí)行前,查詢優(yōu)化器會(huì)根據(jù)連接條件,列出幾組可能的連接方案并從中找出系統(tǒng)開銷最小的最佳方案。連接條件要充份考慮帶有索引的表、行數(shù)多的表;內(nèi)外表的選擇可由公式:外層表中的匹配行數(shù)*內(nèi)層表中每一次查找的次數(shù)確定,乘積最小為最佳方案    5.where子句中對(duì)列的任何操作結(jié)果都是在sql運(yùn)行時(shí)逐列計(jì)算得到的,因此它不得不進(jìn)行表搜索,而沒有使用該列上面的索引;如果這些結(jié)果在查詢編譯時(shí)就能得到,那么就可以被sql優(yōu)化器優(yōu)化,使用索引,避免表搜索(例:select * from record where substring(card_no,1,4)=’5378’ && select * from record where card_no like ’5378%’)任何對(duì)列的操作都將導(dǎo)致表掃描,它包括數(shù)據(jù)庫函數(shù)、計(jì)算表達(dá)式等等,查詢時(shí)要盡可能將操作移至等號(hào)右邊    6.where條件中的’in’在邏輯上相當(dāng)于’or’,所以語法分析器會(huì)將in ('0','1')轉(zhuǎn)化為column='0' or column='1'來執(zhí)行。我們期望它會(huì)根據(jù)每個(gè)or子句分別查找,再將結(jié)果相加,這樣可以利用column上的索引;但實(shí)際上它卻采用了"or策略",即先取出滿足每個(gè)or子句的行,存入臨時(shí)數(shù)據(jù)庫的工作表中,再建立唯一索引以去掉重復(fù)行,最后從這個(gè)臨時(shí)表中計(jì)算結(jié)果。因此,實(shí)際過程沒有利用column上索引,并且完成時(shí)間還要受tempdb數(shù)據(jù)庫性能的影響。in、or子句常會(huì)使用工作表,使索引失效;如果不產(chǎn)生大量重復(fù)值,可以考慮把子句拆開;拆開的子句中應(yīng)該包含索引    7.要善于使用存儲(chǔ)過程,它使sql變得更加靈活和高效 索引使用原則:

1、使用索引來更快地遍歷表。 缺省情況下建立的索引是非群集索引,但有時(shí)它并不是最佳的。在非群集索引下,數(shù)據(jù)在物理上隨機(jī)存放在數(shù)據(jù)頁上。合理的索引設(shè)計(jì)要建立在 對(duì)各種查詢的分析和預(yù)測(cè)上。一般來說: a.有大量重復(fù)值、且經(jīng)常有范圍查詢( > ,< ,> =,< =)和order by、group by發(fā)生的列,可考 慮建立群集索引; b.經(jīng)常同時(shí)存取多列,且每列都含有重復(fù)值可考慮建立組合索引; c.組合索引要盡量使關(guān)鍵查詢形成索引覆蓋,其前導(dǎo)列一定是使用最頻繁的列。索引雖有助于提高性能但不是索引越多越好,恰好相反過多的索引會(huì)導(dǎo)致系統(tǒng)低效。用戶在表中每加進(jìn)一個(gè)索引,維護(hù)索引集合就要做相應(yīng)的更新工作。 2、在海量查詢時(shí)盡量少用格式轉(zhuǎn)換。 3、ORDER BY和GROPU BY使用ORDER BY和GROUP BY短語,任何一種索引都有助于SELECT的性能提高。 7、任何對(duì)列的操作都將導(dǎo)致表掃描,它包括數(shù)據(jù)庫函數(shù)、計(jì)算表達(dá)式等等,查詢時(shí)要盡可能將操作移至等號(hào)右邊。 4、IN、OR子句常會(huì)使用工作表,使索引失效。如果不產(chǎn)生大量重復(fù)值,可以考慮把子句拆開。拆開的子句中應(yīng)該包含索引。

Sql的優(yōu)化原則2: 1、只要能滿足你的需求,應(yīng)盡可能使用更小的數(shù)據(jù)類型:例如使用MEDIUMINT代替INT 2、盡量把所有的列設(shè)置為NOT NULL,如果你要保存NULL,手動(dòng)去設(shè)置它,而不是把它設(shè)為默認(rèn)值。 3、盡量少用VARCHAR、TEXT、BLOB類型 4、如果你的數(shù)據(jù)只有你所知的少量的幾個(gè)。最好使用ENUM類型 5、正如graymice所講的那樣,建立索引。 以下是我做的一個(gè)實(shí)驗(yàn),可以發(fā)現(xiàn)索引能極大地提高查詢的效率:

我有一個(gè)會(huì)員信息表users,里邊有37365條用戶記錄:

在不加索引的時(shí)候進(jìn)行查詢: sql語句A: select * from users where username like ’%許%’; 在MySQL-Front中的8次查詢時(shí)長為:1.40,0.54,0.54,0.54,0.53,0.55,0.54 共找到960條記錄

sql語句B: select * from users where username like ’許%’; 在Mysql-Front中的8次查詢時(shí)長為:0.53,0.53,0.53,0.54,0.53,0.53,0.54,0.54 共找到836條記錄

sql語句C: select * from users where username like ’%許’; 在Mysql-Front中的8次查詢時(shí)長為:0.51,0.51,0.52,0.52,0.51,0.51,0.52,0.51 共找到7條記錄

為username列添加索引: create index usernameindex on users(username(6));

再次查詢: sql語句A: select * from users where username like ’%許%’; 在Mysql-Front中的8次查詢時(shí)長為:0.35,0.34,0.34,0.35,0.34,0.34,0.35,0.34 共找到960條記錄

sql語句B: select * from users where username like ’許%’; 在Mysql-Front中的8次查詢時(shí)長為:0.06,0.07,0.07,0.07,0.07,0.07,0.06,0.06 共找到836條記錄

sql語句C: select * from users where username like ’%許’; 在Mysql-Front中的8次查詢時(shí)長為:0.32,0.31,0.31,0.32,0.31,0.32,0.31,0.31 共找到7條記錄

在實(shí)驗(yàn)過程中,我沒有另開任何程序,以上的數(shù)據(jù)說明在單表查詢中,建立索引的可以極大地提高查詢速度。 另外要說的是如果建立了索引,對(duì)于like ’許%’類型的查詢,速度提升是最明顯的。因此,我們?cè)趯憇ql語句的時(shí)候也盡量采用這種方式查詢。

對(duì)于多表查詢我們的優(yōu)化原則是:

盡量將索引建立在:left join on/right join on ... +條件,的條件語句中所涉及的字段上。

多表查詢比單表查詢更能體現(xiàn)索引的優(yōu)勢(shì)。

6、索引的建立原則: 如果一列的中數(shù)據(jù)的前綴重復(fù)值很少,我們最好就只索引這個(gè)前綴。Mysql支持這種索引。我在上面用到的索引方法就是對(duì)username最左邊的6個(gè)字符進(jìn)行索引。索引越短,占用的

磁盤空間越少,在檢索過程中花的時(shí)間也越少。這方法可以對(duì)最多左255個(gè)字符進(jìn)行索引。

在很多場(chǎng)合,我們可以給建立多列數(shù)據(jù)建立索引。

索引應(yīng)該建立在查詢條件中進(jìn)行比較的字段上,而不是建立在我們要找出來并且顯示的字段上

7、限制索引的使用的避歸。7.1  IN、OR子句常會(huì)使用工作表,使索引失效。如果不產(chǎn)生大量重復(fù)值,可以考慮把子句拆開。拆開的子句中應(yīng)該包含索引。這句話怎么理解決,請(qǐng)舉個(gè)例子

例子如下: 如果在fields1和fields2上同時(shí)建立了索引,fields1為主索引 以下sql會(huì)用到索引 select * from tablename1 where fields1=’value1’ and fields2=’value2’ 以下sql不會(huì)用到索引 select * from tablename1 where fields1=’value1’ or fields2=’value2’ 7.2 使用IS NULL 或IS NOT NULL         使用IS NULL 或IS NOT NULL同樣會(huì)限制索引的使用。因?yàn)镹ULL值并沒有被定義。在SQL語句中使用NULL會(huì)有很多的麻煩。因此建議開     發(fā)人員在建表時(shí),把需要索引的列設(shè)成NOT NULL。如果被索引的列在某些行中存在NULL值,就不會(huì)使用這個(gè)索引(除非索引是一個(gè)位圖索引,關(guān)于位圖索引在稍后在詳細(xì)討論)。

7.3 使用函數(shù)如果不使用基于函數(shù)的索引,那么在SQL語句的WHERE子句中對(duì)存在索引的列使用函數(shù)時(shí),會(huì)使優(yōu)化器忽略掉這些索引。下面的查詢不會(huì)使用索引(只要它不是基于函數(shù)的索引)   select empno,ename,deptno          from   emp          where  trunc(hiredate)='01-MAY-81';          把上面的語句改成下面的語句,這樣就可以通過索引進(jìn)行查找。          select empno,ename,deptno          from   emp          where  hiredate<(to_date('01-MAY-81')+0.9999);

7.4 比較不匹配的數(shù)據(jù)類型比較不匹配的數(shù)據(jù)類型也是比較難于發(fā)現(xiàn)的性能問題之一。注意下面查詢的例子,account_number是一個(gè)VARCHAR2類型,在account_number字段上有索引。下面的語句將執(zhí)行全表掃描。         select bank_name,address,city,state,zip         from   banks         where  account_number = 990354;         Oracle可以自動(dòng)把where子句變成to_number(account_number)=990354,這樣就限制了索引的使用,改成下面的查詢就可以使用索引:         select bank_name,address,city,state,zip         from   banks         where  account_number ='990354';     特別注意:不匹配的數(shù)據(jù)類型之間比較會(huì)讓Oracle自動(dòng)限制索引的使用,即便對(duì)這個(gè)查詢執(zhí)行Explain Plan也不能讓您明白為什么做了一               次“全表掃描”。

補(bǔ)充: 1.索引帶來查詢上的速度的大大提升,但索引也占用了額外的硬盤空間(當(dāng)然現(xiàn)在一般硬盤空間不成問題),而且往表中插入新記錄時(shí)索引也要隨著更新這也需要一定時(shí)間. 有些表如果經(jīng)常insert,而較少select,就不用加索引了.不然每次寫入數(shù)據(jù)都要重新改寫索引,花費(fèi)時(shí)間; 這個(gè)視實(shí)際情況而定,通常情況下索引是必需的. 2.我在對(duì)查詢效率有懷疑的時(shí)候,一般是直接用Mysql的Explain來跟蹤查詢情況. 你用Mysql-Front是通過時(shí)長來比較,我覺得如果從查詢時(shí)掃描字段的次數(shù)來比較更精準(zhǔn)寫。


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 永兴县| 上蔡县| 长泰县| 锡林浩特市| 柘荣县| 买车| 公主岭市| 奉节县| 汉沽区| 桐柏县| 安达市| 高雄县| 宜昌市| 宽城| 武功县| 项城市| 临沂市| 资中县| 浦东新区| 沽源县| 金乡县| 宿松县| 伊吾县| 龙里县| 广水市| 达拉特旗| 光山县| 土默特左旗| 河北区| 福贡县| 介休市| 织金县| 汽车| 基隆市| 荃湾区| 湘潭市| 胶州市| 濉溪县| 嫩江县| 瓦房店市| 镇宁|