亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解mysql索引總結(jié)----mysql索引類(lèi)型以及創(chuàng)建

 更新時(shí)間:2016年11月28日 11:05:57   作者:xluren  
索引是一種特殊的文件(InnoDB數(shù)據(jù)表上的索引是表空間的一個(gè)組成部分),它們包含著對(duì)數(shù)據(jù)表里所有記錄的引用指針。這篇文章主要介紹了詳解mysql索引總結(jié)----mysql索引類(lèi)型以及創(chuàng)建,有興趣的可以了解一下。

關(guān)于MySQL索引的好處,如果正確合理設(shè)計(jì)并且使用索引的MySQL是一輛蘭博基尼的話,那么沒(méi)有設(shè)計(jì)和使用索引的MySQL就是一個(gè)人力三輪車(chē)。對(duì)于沒(méi)有索引的表,單表查詢(xún)可能幾十萬(wàn)數(shù)據(jù)就是瓶頸,而通常大型網(wǎng)站單日就可能會(huì)產(chǎn)生幾十萬(wàn)甚至幾百萬(wàn)的數(shù)據(jù),沒(méi)有索引查詢(xún)會(huì)變的非常緩慢。還是以WordPress來(lái)說(shuō),其多個(gè)數(shù)據(jù)表都會(huì)對(duì)經(jīng)常被查詢(xún)的字段添加索引,比如wp_comments表中針對(duì)5個(gè)字段設(shè)計(jì)了BTREE索引。

 一個(gè)簡(jiǎn)單的對(duì)比測(cè)試

以我去年測(cè)試的數(shù)據(jù)作為一個(gè)簡(jiǎn)單示例,20多條數(shù)據(jù)源隨機(jī)生成200萬(wàn)條數(shù)據(jù),平均每條數(shù)據(jù)源都重復(fù)大概10萬(wàn)次,表結(jié)構(gòu)比較簡(jiǎn)單,僅包含一個(gè)自增ID,一個(gè)char類(lèi)型,一個(gè)text類(lèi)型和一個(gè)int類(lèi)型,單表2G大小,使用MyIASM引擎。開(kāi)始測(cè)試未添加任何索引。

執(zhí)行下面的SQL語(yǔ)句:

mysql> SELECT id,FROM_UNIXTIME(time) FROM article WHERE a.title='測(cè)試標(biāo)題' 

查詢(xún)需要的時(shí)間非??植赖?,如果加上聯(lián)合查詢(xún)和其他一些約束條件,數(shù)據(jù)庫(kù)會(huì)瘋狂的消耗內(nèi)存,并且會(huì)影響前端程序的執(zhí)行。這時(shí)給title字段添加一個(gè)BTREE索引:

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

再次執(zhí)行上述查詢(xún)語(yǔ)句,其對(duì)比非常明顯:

MySQL索引的概念

索引是一種特殊的文件(InnoDB數(shù)據(jù)表上的索引是表空間的一個(gè)組成部分),它們包含著對(duì)數(shù)據(jù)表里所有記錄的引用指針。更通俗的說(shuō),數(shù)據(jù)庫(kù)索引好比是一本書(shū)前面的目錄,能加快數(shù)據(jù)庫(kù)的查詢(xún)速度。上述SQL語(yǔ)句,在沒(méi)有索引的情況下,數(shù)據(jù)庫(kù)會(huì)遍歷全部200條數(shù)據(jù)后選擇符合條件的;而有了相應(yīng)的索引之后,數(shù)據(jù)庫(kù)會(huì)直接在索引中查找符合條件的選項(xiàng)。如果我們把SQL語(yǔ)句換成“SELECT * FROM article WHERE id=2000000”,那么你是希望數(shù)據(jù)庫(kù)按照順序讀取完200萬(wàn)行數(shù)據(jù)以后給你結(jié)果還是直接在索引中定位呢?上面的兩個(gè)圖片鮮明的用時(shí)對(duì)比已經(jīng)給出了答案(注:一般數(shù)據(jù)庫(kù)默認(rèn)都會(huì)為主鍵生成索引)。

索引分為聚簇索引和非聚簇索引兩種,聚簇索引是按照數(shù)據(jù)存放的物理位置為順序的,而非聚簇索引就不一樣了;聚簇索引能提高多行檢索的速度,而非聚簇索引對(duì)于單行的檢索很快。

 MySQL索引的類(lèi)型

1. 普通索引

這是最基本的索引,它沒(méi)有任何限制,比如上文中為title字段創(chuàng)建的索引就是一個(gè)普通索引,MyIASM中默認(rèn)的BTREE類(lèi)型的索引,也是我們大多數(shù)情況下用到的索引。

 –直接創(chuàng)建索引 

CREATE INDEX index_name ON table(column(length)) 

–修改表結(jié)構(gòu)的方式添加索引 

ALTER TABLE table_name ADD INDEX index_name ON (column(length)) 

–創(chuàng)建表的時(shí)候同時(shí)創(chuàng)建索引 

CREATE TABLE `table` ( 


 `id` int(11) NOT NULL AUTO_INCREMENT , 


 `title` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL , 


 `content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL , 


 `time` int(10) NULL DEFAULT NULL , 


 PRIMARY KEY (`id`), 


 INDEX index_name (title(length)) 


 ) 

–刪除索引 

DROP INDEX index_name ON table 

2. 唯一索引

與普通索引類(lèi)似,不同的就是:索引列的值必須唯一,但允許有空值(注意和主鍵不同)。如果是組合索引,則列值的組合必須唯一,創(chuàng)建方法和普通索引類(lèi)似。

–創(chuàng)建唯一索引 


 CREATE UNIQUE INDEX indexName ON table(column(length)) 


 –修改表結(jié)構(gòu) 


 ALTER TABLE table_name ADD UNIQUE indexName ON (column(length)) 


 –創(chuàng)建表的時(shí)候直接指定 


 CREATE TABLE `table` ( 


 `id` int(11) NOT NULL AUTO_INCREMENT , 


 `title` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL , 


 `content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL , 


 `time` int(10) NULL DEFAULT NULL , 


 PRIMARY KEY (`id`), 


 UNIQUE indexName (title(length)) 


 ); 

3. 全文索引(FULLTEXT)

MySQL從3.23.23版開(kāi)始支持全文索引和全文檢索,F(xiàn)ULLTEXT索引僅可用于 MyISAM 表;他們可以從CHAR、VARCHAR或TEXT列中作為CREATE TABLE語(yǔ)句的一部分被創(chuàng)建,或是隨后使用ALTER TABLE 或CREATE INDEX被添加。////對(duì)于較大的數(shù)據(jù)集,將你的資料輸入一個(gè)沒(méi)有FULLTEXT索引的表中,然后創(chuàng)建索引,其速度比把資料輸入現(xiàn)有FULLTEXT索引的速度更為快。不過(guò)切記對(duì)于大容量的數(shù)據(jù)表,生成全文索引是一個(gè)非常消耗時(shí)間非常消耗硬盤(pán)空間的做法。

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

4. 單列索引、多列索引

多個(gè)單列索引與單個(gè)多列索引的查詢(xún)效果不同,因?yàn)閳?zhí)行查詢(xún)時(shí),MySQL只能使用一個(gè)索引,會(huì)從多個(gè)索引中選擇一個(gè)限制最為嚴(yán)格的索引。

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

平時(shí)用的SQL查詢(xún)語(yǔ)句一般都有比較多的限制條件,所以為了進(jìn)一步榨取MySQL的效率,就要考慮建立組合索引。例如上表中針對(duì)title和time建立一個(gè)組合索引:ALTER TABLE article ADD INDEX index_titme_time (title(50),time(10))。建立這樣的組合索引,其實(shí)是相當(dāng)于分別建立了下面兩組組合索引:

–title,time

–title

為什么沒(méi)有time這樣的組合索引呢?這是因?yàn)镸ySQL組合索引“最左前綴”的結(jié)果。簡(jiǎn)單的理解就是只從最左面的開(kāi)始組合。并不是只要包含這兩列的查詢(xún)都會(huì)用到該組合索引,如下面的幾個(gè)SQL所示:

 –使用到上面的索引 
SELECT * FROM article WHREE title='測(cè)試' AND time=1234567890; 
SELECT * FROM article WHREE utitle='測(cè)試';

–不使用上面的索引 
SELECT * FROM article WHREE time=1234567890;

 MySQL索引的優(yōu)化

上面都在說(shuō)使用索引的好處,但過(guò)多的使用索引將會(huì)造成濫用。因此索引也會(huì)有它的缺點(diǎn):雖然索引大大提高了查詢(xún)速度,同時(shí)卻會(huì)降低更新表的速度,如對(duì)表進(jìn)行INSERT、UPDATE和DELETE。因?yàn)楦卤頃r(shí),MySQL不僅要保存數(shù)據(jù),還要保存一下索引文件。建立索引會(huì)占用磁盤(pán)空間的索引文件。一般情況這個(gè)問(wèn)題不太嚴(yán)重,但如果你在一個(gè)大表上創(chuàng)建了多種組合索引,索引文件的會(huì)膨脹很快。索引只是提高效率的一個(gè)因素,如果你的MySQL有大數(shù)據(jù)量的表,就需要花時(shí)間研究建立最優(yōu)秀的索引,或優(yōu)化查詢(xún)語(yǔ)句。下面是一些總結(jié)以及收藏的MySQL索引的注意事項(xiàng)和優(yōu)化方法。

1. 何時(shí)使用聚集索引或非聚集索引?

動(dòng)作描述 使用聚集索引 使用非聚集索引
列經(jīng)常被分組排序 使用 使用
返回某范圍內(nèi)的數(shù)據(jù) 使用 不使用
一個(gè)或極少不同值 不使用 不使用
小數(shù)目的不同值 使用 不使用
大數(shù)目的不同值 不使用 使用
頻繁更新的列 不使用 使用
外鍵列 使用 使用
主鍵列 使用 使用
頻繁修改索引列 不使用 使用

事實(shí)上,我們可以通過(guò)前面聚集索引和非聚集索引的定義的例子來(lái)理解上表。如:返回某范圍內(nèi)的數(shù)據(jù)一項(xiàng)。比如您的某個(gè)表有一個(gè)時(shí)間列,恰好您把聚合索引建立在了該列,這時(shí)您查詢(xún)2004年1月1日至2004年10月1日之間的全部數(shù)據(jù)時(shí),這個(gè)速度就將是很快的,因?yàn)槟倪@本字典正文是按日期進(jìn)行排序的,聚類(lèi)索引只需要找到要檢索的所有數(shù)據(jù)中的開(kāi)頭和結(jié)尾數(shù)據(jù)即可;而不像非聚集索引,必須先查到目錄中查到每一項(xiàng)數(shù)據(jù)對(duì)應(yīng)的頁(yè)碼,然后再根據(jù)頁(yè)碼查到具體內(nèi)容。其實(shí)這個(gè)具體用法我還不是很理解,只能等待后期的項(xiàng)目開(kāi)發(fā)中慢慢學(xué)學(xué)了。

2. 索引不會(huì)包含有NULL值的列

只要列中包含有NULL值都將不會(huì)被包含在索引中,復(fù)合索引中只要有一列含有NULL值,那么這一列對(duì)于此復(fù)合索引就是無(wú)效的。所以我們?cè)跀?shù)據(jù)庫(kù)設(shè)計(jì)時(shí)不要讓字段的默認(rèn)值為NULL。

3. 使用短索引

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

4. 索引列排序

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

5. like語(yǔ)句操作

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

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

例如:select * from users where YEAR(adddate)<2007,將在每個(gè)行上進(jìn)行運(yùn)算,這將導(dǎo)致索引失效而進(jìn)行全表掃描,因此我們可以改成:select * from users where adddate<'2007-01-01′。關(guān)于這一點(diǎn)可以圍觀:一個(gè)單引號(hào)引發(fā)的MYSQL性能損失。

最后總結(jié)一下,MySQL只對(duì)一下操作符才使用索引:<,<=,=,>,>=,between,in,以及某些時(shí)候的like(不以通配符%或_開(kāi)頭的情形)。而理論上每張表里面最多可創(chuàng)建16個(gè)索引,不過(guò)除非是數(shù)據(jù)量真的很多,否則過(guò)多的使用索引也不是那么好玩的,比如我剛才針對(duì)text類(lèi)型的字段創(chuàng)建索引的時(shí)候,系統(tǒng)差點(diǎn)就卡死了。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Mysql處理Duplicate entry ‘6‘ for key ‘PRIMARY‘問(wèn)題及解決

    Mysql處理Duplicate entry ‘6‘ for key 

    這篇文章主要介紹了Mysql處理Duplicate entry ‘6‘ for key ‘PRIMARY‘問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • mysql數(shù)據(jù)庫(kù)查詢(xún)基礎(chǔ)命令詳解

    mysql數(shù)據(jù)庫(kù)查詢(xún)基礎(chǔ)命令詳解

    這篇文章主要介紹了mysql數(shù)據(jù)庫(kù)查詢(xún)基礎(chǔ)命令,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-11-11
  • MySQL查詢(xún)空字段或非空字段(is null和not null)

    MySQL查詢(xún)空字段或非空字段(is null和not null)

    本文介紹在MySQL中,面對(duì)值為空(NULL)的字段,應(yīng)該如何查詢(xún)。怎么判斷一個(gè)字段的值為NULL或不為NULL,需要的朋友可以參考下
    2016-04-04
  • MySQL下將一個(gè)表的數(shù)據(jù)插入到另外一個(gè)表的實(shí)現(xiàn)語(yǔ)句

    MySQL下將一個(gè)表的數(shù)據(jù)插入到另外一個(gè)表的實(shí)現(xiàn)語(yǔ)句

    開(kāi)發(fā)中,我們經(jīng)常需要將一個(gè)表的數(shù)據(jù)插入到另外一個(gè)表,有時(shí)還需要指定導(dǎo)入字段,雖然這個(gè)實(shí)現(xiàn)起來(lái)非常簡(jiǎn)單,但是還是會(huì)困擾許多新手,因此專(zhuān)門(mén)發(fā)一篇文章備查。
    2009-09-09
  • 淺談MySQL數(shù)據(jù)庫(kù)的備份與恢復(fù)

    淺談MySQL數(shù)據(jù)庫(kù)的備份與恢復(fù)

    MYSQL數(shù)據(jù)庫(kù)的備份、恢復(fù)等是每一位信息管理人員應(yīng)必備的能力,因此掌握MYSQL數(shù)據(jù)庫(kù)管理的技巧會(huì)使您的工作事半功倍,這里我們來(lái)簡(jiǎn)單總結(jié)下。
    2017-01-01
  • 淺談mysql雙層not exists查詢(xún)執(zhí)行流程

    淺談mysql雙層not exists查詢(xún)執(zhí)行流程

    本文主要介紹了淺談mysql雙層not?exists查詢(xún)執(zhí)行流程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • 解決Navicat for Mysql連接報(bào)錯(cuò)1251的問(wèn)題(連接失敗)

    解決Navicat for Mysql連接報(bào)錯(cuò)1251的問(wèn)題(連接失敗)

    記得在之前給大家介紹過(guò)Navicat for Mysql連接報(bào)錯(cuò)的問(wèn)題,可能寫(xiě)的不夠詳細(xì),今天在稍作修改補(bǔ)充下,對(duì)Navicat for Mysql連接報(bào)錯(cuò)1251問(wèn)題感興趣的朋友跟隨小編一起看看吧
    2021-05-05
  • MySQL?時(shí)間類(lèi)型用?datetime,?timestamp?還是?integer?更好

    MySQL?時(shí)間類(lèi)型用?datetime,?timestamp?還是?integer?更好

    這篇文章主要介紹了MySQL?時(shí)間類(lèi)型用datetime,timestamp還是integer更好,文章通過(guò)圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-09-09
  • mysql5.7.18.zip免安裝版本配置教程(windows)

    mysql5.7.18.zip免安裝版本配置教程(windows)

    這篇文章主要為大家詳細(xì)介紹了mysql5.7.18.zip安裝教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • 深入解析MySQL雙寫(xiě)緩沖區(qū)

    深入解析MySQL雙寫(xiě)緩沖區(qū)

    雙寫(xiě)緩沖區(qū)是MySQL中的一種優(yōu)化方式,主要用于提高數(shù)據(jù)的寫(xiě)性能,本文將介紹Doublewrite Buffer的原理和應(yīng)用,幫助讀者深入理解其如何提高M(jìn)ySQL的數(shù)據(jù)可靠性并防止可能的數(shù)據(jù)損壞,感興趣的可以了解一下
    2024-02-02

最新評(píng)論