最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解MySQL單列索引和聯(lián)合索引

 更新時(shí)間:2022年09月22日 14:36:29   作者:哪 吒  
聯(lián)合索引的結(jié)構(gòu)與電話簿類似,人名由姓和名構(gòu)成,電話簿首先按姓氏進(jìn)行排序,然后按名字對(duì)有相同姓氏的人進(jìn)行排序,這篇文章主要介紹了MySQL單列索引和聯(lián)合索引,需要的朋友可以參考下

一、簡(jiǎn)介

利用索引中的附加列,可以縮小搜索的范圍,但使用一個(gè)具有兩列的索引不同于使用兩個(gè)單獨(dú)的索引。

聯(lián)合索引的結(jié)構(gòu)與電話簿類似,人名由姓和名構(gòu)成,電話簿首先按姓氏進(jìn)行排序,然后按名字對(duì)有相同姓氏的人進(jìn)行排序。如果您知道姓,電話簿將非常有用,如果您知道姓和名,電話簿則更為有用,但如果您只知道名不知道姓,電話簿將沒(méi)有用處。

所以說(shuō)創(chuàng)建聯(lián)合索引時(shí),應(yīng)該仔細(xì)考慮列的順序。對(duì)索引中的所有列執(zhí)行搜索或僅對(duì)前幾列執(zhí)行搜索時(shí),聯(lián)合索引非常有用;僅對(duì)后面的任意列執(zhí)行搜索時(shí),聯(lián)合索引則沒(méi)有用處。

二、單列索引

多個(gè)單列索引在多條件查詢時(shí)優(yōu)化器會(huì)優(yōu)先選擇最優(yōu)索引策略,可能只用一個(gè)索引,也可能將多個(gè)索引全用上。但多個(gè)單列索引底層會(huì)創(chuàng)建多個(gè)B+索引樹(shù),比較占用空間,也會(huì)浪費(fèi)一定搜索效率,故如果只有多條件聯(lián)合查詢時(shí)最好建聯(lián)合索引。

三、最左前綴原則

顧名思義是最左優(yōu)先,以最左邊的為起點(diǎn)任何連續(xù)的索引都能匹配上,如果第一個(gè)字段是范圍查詢需要單獨(dú)建一個(gè)索引,在創(chuàng)建聯(lián)合索引時(shí),要根據(jù)業(yè)務(wù)需求,where子句中使用最頻繁的一列放在最左邊。這樣的話擴(kuò)展性比較好,比如username經(jīng)常需要作為查詢條件,而age不常使用,則需要把username放在聯(lián)合索引的第一位置,即最左邊。

1、創(chuàng)建復(fù)合索引

ALTER TABLE employee ADD INDEX idx_name_salary (name,salary)

2、滿足復(fù)合索引的最左特性,哪怕只是部分,復(fù)合索引生效

SELECT * FROM employee WHERE NAME='哪吒編程'

3、沒(méi)有出現(xiàn)左邊的字段,則不滿足最左特性,索引失效

SELECT * FROM employee WHERE salary=5000

4、復(fù)合索引全使用,按左側(cè)順序出現(xiàn) name,salary,索引生效

SELECT * FROM employee WHERE NAME='哪吒編程' AND salary=5000

5、雖然違背了最左特性,但MySQL執(zhí)行SQL時(shí)會(huì)進(jìn)行優(yōu)化,底層進(jìn)行顛倒優(yōu)化

SELECT * FROM employee WHERE salary=5000 AND NAME='哪吒編程'

6、理由

復(fù)合索引也稱為聯(lián)合索引,當(dāng)我們創(chuàng)建一個(gè)聯(lián)合索引的時(shí)候,如(k1,k2,k3),相當(dāng)于創(chuàng)建了(k1)、(k1,k2)和(k1,k2,k3)三個(gè)索引,這就是最左匹配原則。

聯(lián)合索引不滿足最左原則,索引一般會(huì)失效。

四、同時(shí)存在聯(lián)合索引和單列索引(字段有重復(fù))

這個(gè)時(shí)候查詢mysql會(huì)怎么用索引呢?

這個(gè)涉及到MySQL本身的查詢優(yōu)化器策略,當(dāng)一個(gè)表有多條索引可走時(shí),mysql根據(jù)查詢語(yǔ)句的成本來(lái)選擇走哪條索引;

有人說(shuō)where查詢是按照從左到右的順序,所以篩選力度大的條件盡量放在前面。網(wǎng)上百度過(guò),確實(shí)有這種說(shuō)法,但我親自測(cè)試過(guò),MySQL執(zhí)行優(yōu)化器會(huì)對(duì)其進(jìn)行優(yōu)化,當(dāng)不考慮索引時(shí),where條件順序?qū)π蕸](méi)有影響,真正有影響的是是否用到了索引!

五、聯(lián)合索引本質(zhì)

當(dāng)創(chuàng)建**(a, b, c)聯(lián)合索引時(shí),相當(dāng)于創(chuàng)建了(a)單列索引,(a, b)聯(lián)合索引以及(a, b, c)聯(lián)合索引,想要索引生效的話,只能使用者三種組合;當(dāng)然,我們上面測(cè)試過(guò),a, c組合也可以,但實(shí)際上只用到了a的索引,c并沒(méi)有用到。

六、索引失效

1、like子查詢,%放前面;

2、非空判斷 is not null;or語(yǔ)句前后沒(méi)有同時(shí)使用索引。當(dāng)or左右查詢字段只有一個(gè)是索引,該索引失效,只有當(dāng)or左右查詢字段均為索引時(shí),才會(huì)生效;

3、or語(yǔ)句(前后都有索引才行,SQL優(yōu)化要避免寫or語(yǔ)句);

4、數(shù)據(jù)類型出現(xiàn)隱式轉(zhuǎn)化。如varchar不加單引號(hào)的話可能會(huì)自動(dòng)轉(zhuǎn)換為int型,使索引無(wú)效,產(chǎn)生全表掃描。

七、其它知識(shí)點(diǎn)

1、需要加索引的字段,要在where條件中

2、數(shù)據(jù)量少的字段不需要加索引,因?yàn)榻ㄋ饕幸欢ㄩ_(kāi)銷,如果數(shù)據(jù)量小則沒(méi)有必要建索引,速度范圍慢。

3、聯(lián)合索引比每個(gè)列建索引更有優(yōu)勢(shì),因?yàn)樗饕⒌迷蕉嗑驮秸即疟P空間,在更新數(shù)據(jù)的時(shí)候速度會(huì)越慢、另外建立多列索引時(shí),順序也是需要注意的,應(yīng)該講嚴(yán)格的索引放在前面,這樣篩選的力度會(huì)更大,效率更高。

八、MySQL存儲(chǔ)引擎簡(jiǎn)介

1、InnoDB

支持事務(wù)處理,支持外鍵,支持崩潰修復(fù)能力和并發(fā)控制。如果需要對(duì)事務(wù)的完整性要求比較高(比如銀行),要求實(shí)現(xiàn)并發(fā)控制(比如售票),那選擇InnoDB有很大的優(yōu)勢(shì)。如果需要頻繁的更新、刪除操作的數(shù)據(jù)庫(kù),也可以選擇InnoDB,因?yàn)橹С质聞?wù)的提交和回滾。

2、MyISAM

插入速度快,空間和內(nèi)存使用比較低。如果表主要是用于插入新紀(jì)錄和讀取記錄,那么選擇MyISAM能實(shí)現(xiàn)處理高效率。如果應(yīng)用的完整性、并發(fā)要求比較低,也可以使用。

注意,同一個(gè)數(shù)據(jù)庫(kù)也可以使用多種存儲(chǔ)引擎的表。如果一個(gè)表要求比較高的事務(wù)處理,可以選擇InnoDB。這個(gè)數(shù)據(jù)庫(kù)中可以將查詢要求比較高的表選擇MyISAM存儲(chǔ)。如果該數(shù)據(jù)庫(kù)需要一個(gè)用于查詢的臨時(shí)表,可以選擇MEMORY存儲(chǔ)引擎。

九、索引結(jié)構(gòu)(方法、算法)

在mysql中常用兩種索引結(jié)構(gòu)(算法)BTree和Hash,兩種算法檢索方式不一樣,對(duì)查詢的作用也不一樣。

1、Hash

Hash索引的底層實(shí)現(xiàn)是由Hash表來(lái)實(shí)現(xiàn)的,非常適合以 key-value 的形式查詢,也就是單個(gè)key 查詢,或者說(shuō)是等值查詢。

Hash 索引可以比較方便的提供等值查詢的場(chǎng)景,由于是一次定位數(shù)據(jù),不像BTree索引需 要從根節(jié)點(diǎn)到枝節(jié)點(diǎn),最后才能訪問(wèn)到頁(yè)節(jié)點(diǎn)這樣多次IO訪問(wèn),所以檢索效率遠(yuǎn)高于BTree索引。但是對(duì)于范圍查詢的話,就需要進(jìn)行全表掃描了。

但為什么我們使用BTree比使用Hash多呢?主要Hash本身由于其特殊性,也帶來(lái)了很多限制和弊端:

  • Hash索引僅僅能滿足“=”,“IN”,“<=>”查詢,不能使用范圍查詢。
  • 聯(lián)合索引中,Hash索引不能利用部分索引鍵查詢。 對(duì)于聯(lián)合索引中的多個(gè)列,Hash是要么全部使用,要么全部不使用,并不支持BTree支持的聯(lián)合索引的最優(yōu)前綴,也就是聯(lián)合索引的前面一個(gè)或幾個(gè)索引鍵進(jìn)行查詢時(shí),Hash索引無(wú)法被利用。
  • Hash索引無(wú)法避免數(shù)據(jù)的排序操作 由于Hash索引中存放的是經(jīng)過(guò)Hash計(jì)算之后的Hash值,而且Hash值的大小關(guān)系并不一定和Hash運(yùn)算前的鍵值完全一樣,所以數(shù)據(jù)庫(kù)無(wú)法利用索引的數(shù)據(jù)來(lái)避免任何排序運(yùn)算。
  • Hash索引任何時(shí)候都不能避免表掃描 Hash索引是將索引鍵通過(guò)Hash運(yùn)算之后,將Hash運(yùn)算結(jié)果的Hash值和所對(duì)應(yīng)的行指針信息存放于一個(gè)Hash表中,由于不同索引鍵存在相同Hash值,所以即使?jié)M足某個(gè)Hash鍵值的數(shù)據(jù)的記錄條數(shù),也無(wú)法從Hash索引中直接完成查詢,還是要通過(guò)訪問(wèn)表中的實(shí)際數(shù)據(jù)進(jìn)行比較,并得到相應(yīng)的結(jié)果。
  • Hash索引遇到大量Hash值相等的情況后性能并不一定會(huì)比BTree高 對(duì)于選擇性比較低的索引鍵,如果創(chuàng)建Hash索引,那么將會(huì)存在大量記錄指針信息存于同一個(gè)Hash值相關(guān)聯(lián)。這樣要定位某一條記錄時(shí)就會(huì)非常麻煩,會(huì)浪費(fèi)多次表數(shù)據(jù)訪問(wèn),而造成整體性能底下。

2、B+ Tree

B+Tree索引是最常用的mysql數(shù)據(jù)庫(kù)索引算法,因?yàn)樗粌H可以被用在=,>,>=,<,<=和between這些比較操作符上,而且還可以用于like操作符,只要它的查詢條件是一個(gè)不以通配符開(kāi)頭的常量,

例如:

select * from user where name like 'jack%'; select * from user where name like 'jac%k%';

如果一通配符開(kāi)頭,或者沒(méi)有使用常量,則不會(huì)使用索引,

例如:

select * from user where name like '%jack'; select * from user where name like simply_name;

3、 B+/-Tree原理

在數(shù)據(jù)庫(kù)中,數(shù)據(jù)量相對(duì)較大,多路查找樹(shù)顯然更加適合數(shù)據(jù)庫(kù)的應(yīng)用場(chǎng)景,接下來(lái)我們就介紹這兩類多路查找樹(shù),畢竟作為程序員,心里沒(méi)點(diǎn)B樹(shù)怎么能行呢?

B樹(shù):B樹(shù)就是B-樹(shù),他有著如下的特性:

  • B樹(shù)不同于二叉樹(shù),他們的一個(gè)節(jié)點(diǎn)可以存儲(chǔ)多個(gè)關(guān)鍵字和多個(gè)子樹(shù)指針,這就是B+樹(shù)的特點(diǎn);
  • 一個(gè)m階的B樹(shù)要求除了根節(jié)點(diǎn)以外,所有的非葉子子節(jié)點(diǎn)必須要有[m/2,m]個(gè)子樹(shù);
  • 根節(jié)點(diǎn)必須只能有兩個(gè)子樹(shù),當(dāng)然,如果只有根節(jié)點(diǎn)一個(gè)節(jié)點(diǎn)的情況存在;
  • B樹(shù)是一個(gè)查找二叉樹(shù),這點(diǎn)和二叉查找樹(shù)很像,他都是越靠前的子樹(shù)越小,并且,同一個(gè)節(jié)點(diǎn)內(nèi),關(guān)鍵字按照大小排序;
  • B樹(shù)的一個(gè)節(jié)點(diǎn)要求子樹(shù)的個(gè)數(shù)等于關(guān)鍵字的個(gè)數(shù)+1;

B+樹(shù)就是B樹(shù)的plus版

  • B+樹(shù)將所有的查找結(jié)果放在葉子節(jié)點(diǎn)中,這也就意味著查找B+樹(shù),就必須到葉子節(jié)點(diǎn)才能返回結(jié)果;
  • B+樹(shù)每一個(gè)節(jié)點(diǎn)的關(guān)鍵字個(gè)數(shù)和子樹(shù)指針個(gè)數(shù)相同;
  • B+樹(shù)的非葉子節(jié)點(diǎn)的每一個(gè)關(guān)鍵字對(duì)應(yīng)一個(gè)指針,而關(guān)鍵字則是子樹(shù)的最大,或者最小值;

將上一節(jié)中的B-Tree優(yōu)化,由于B+Tree的非葉子節(jié)點(diǎn)只存儲(chǔ)鍵值信息,假設(shè)每個(gè)磁盤塊能存儲(chǔ)4個(gè)鍵值及指針信息,則變成B+Tree后其結(jié)構(gòu)如下圖所示:

通常在B+Tree上有兩個(gè)頭指針,一個(gè)指向根節(jié)點(diǎn),另一個(gè)指向關(guān)鍵字最小的葉子節(jié)點(diǎn),而且所有葉子節(jié)點(diǎn)(即數(shù)據(jù)節(jié)點(diǎn))之間是一種鏈?zhǔn)江h(huán)結(jié)構(gòu)。因此可以對(duì)B+Tree進(jìn)行兩種查找運(yùn)算:一種是對(duì)于主鍵的范圍查找和分頁(yè)查找,另一種是從根節(jié)點(diǎn)開(kāi)始,進(jìn)行隨機(jī)查找。

可能上面例子中只有22條數(shù)據(jù)記錄,看不出B+Tree的優(yōu)點(diǎn),下面做一個(gè)推算:

InnoDB存儲(chǔ)引擎中頁(yè)的大小為16KB,一般表的主鍵類型為INT(占用4個(gè)字節(jié))或BIGINT(占用8個(gè)字節(jié)),指針類型也一般為4或8個(gè)字節(jié),也就是說(shuō)一個(gè)頁(yè)(B+Tree中的一個(gè)節(jié)點(diǎn))中大概存儲(chǔ)16KB/(8B+8B)=1K個(gè)鍵值(因?yàn)槭枪乐?,為方便?jì)算,這里的K取值為〖10〗^3)。
也就是說(shuō)一個(gè)深度為3的B+Tree索引可以維護(hù)10^3 * 10^3 * 10^3 = 10億條記錄。

實(shí)際情況中每個(gè)節(jié)點(diǎn)可能不能填充滿,因此在數(shù)據(jù)庫(kù)中,B+Tree的高度一般都在2-4層。MySQL的InnoDB存儲(chǔ)引擎在設(shè)計(jì)時(shí)是將根節(jié)點(diǎn)常駐內(nèi)存的,也就是說(shuō)查找某一鍵值的行記錄時(shí)最多只需要1~3次磁盤I/O操作。

數(shù)據(jù)庫(kù)中的B+Tree索引可以分為聚集索引(clustered index)和輔助索引(secondary index)。上面的B+Tree示例圖在數(shù)據(jù)庫(kù)中的實(shí)現(xiàn)即為聚集索引,聚集索引的B+Tree中的葉子節(jié)點(diǎn)存放的是整張表的行記錄數(shù)據(jù)。輔助索引與聚集索引的區(qū)別在于輔助索引的葉子節(jié)點(diǎn)并不包含行記錄的全部數(shù)據(jù),而是存儲(chǔ)相應(yīng)行數(shù)據(jù)的聚集索引鍵,即主鍵。當(dāng)通過(guò)輔助索引來(lái)查詢數(shù)據(jù)時(shí),InnoDB存儲(chǔ)引擎會(huì)遍歷輔助索引找到主鍵,然后再通過(guò)主鍵在聚集索引中找到完整的行記錄數(shù)據(jù)。

到此這篇關(guān)于MySQL單列索引和聯(lián)合索引的文章就介紹到這了,更多相關(guān)MySQL單列索引和聯(lián)合索引內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MySQL性能分析工具profile使用教程

    MySQL性能分析工具profile使用教程

    這篇文章主要介紹了MySQL性能分析工具profile使用教程,本文描述了如何使用MySQL profile,不涉及具體的樣例分析,需要的朋友可以參考下
    2014-10-10
  • 詳解 Mysql中的delimiter定義及作用

    詳解 Mysql中的delimiter定義及作用

    delimiter是mysql分隔符,在mysql客戶端中分隔符默認(rèn)是分號(hào)(;)。如果一次輸入的語(yǔ)句較多,并且語(yǔ)句中間有分號(hào),這時(shí)需要新指定一個(gè)特殊的分隔符。這篇文章給大家介紹了Mysql中的delimiter的作用,感興趣的朋友一起看看吧
    2018-09-09
  • 最新mysql 5.7.23安裝配置圖文教程

    最新mysql 5.7.23安裝配置圖文教程

    這篇文章主要為大家詳細(xì)介紹了最新 mysql 5.7.23 安裝配置圖文教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • Mysql5.7如何修改root密碼

    Mysql5.7如何修改root密碼

    mysql修改管理員root的密碼是個(gè)很常見(jiàn)的問(wèn)題了,網(wǎng)上也有很多的教程,然而新版的MYSQL5.7卻能使用之前的教程,小編經(jīng)過(guò)一番摸索,才找到了修改辦法,這里分享給大家。
    2016-01-01
  • 關(guān)于SQL嵌套的誤解分析

    關(guān)于SQL嵌套的誤解分析

    之前我曾一直以為:就是在sql語(yǔ)句嵌套時(shí),嵌套查詢的約束和外層的約束是沒(méi)有關(guān)系的。
    2010-12-12
  • Win10環(huán)境下安裝Mysql5.7.23問(wèn)題及遇到的坑

    Win10環(huán)境下安裝Mysql5.7.23問(wèn)題及遇到的坑

    這篇文章主要介紹了Win10環(huán)境下安裝Mysql5.7.23問(wèn)題及遇到的坑,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-11-11
  • Mysql行鎖和表鎖的實(shí)現(xiàn)示例

    Mysql行鎖和表鎖的實(shí)現(xiàn)示例

    行鎖和表鎖是兩種常見(jiàn)的鎖定機(jī)制,本文主要介紹了Mysql行鎖和表鎖,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-08-08
  • MySQL兩個(gè)表的親密接觸-連接查詢的原理分析

    MySQL兩個(gè)表的親密接觸-連接查詢的原理分析

    這篇文章主要介紹了MySQL兩個(gè)表的親密接觸-連接查詢的原理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • 怎樣設(shè)置才能允許外網(wǎng)訪問(wèn)MySQL

    怎樣設(shè)置才能允許外網(wǎng)訪問(wèn)MySQL

    大多數(shù)情況下,mysql數(shù)據(jù)庫(kù)只要本機(jī)訪問(wèn)就可以了,這樣的話,默認(rèn)安裝就OK,但是如果需要外網(wǎng)訪問(wèn)mysql數(shù)據(jù)庫(kù)的話,應(yīng)該如何操作呢,想知道的話,就好好看看下面的介紹吧
    2014-08-08
  • windows系統(tǒng)中MySQL和SQLyog的安裝和配置教程

    windows系統(tǒng)中MySQL和SQLyog的安裝和配置教程

    這篇文章主要介紹了windows系統(tǒng)中MySQL和SQLyog的安裝和配置教程的相關(guān)資料,包括下載MySQL、解壓、設(shè)置環(huán)境變量、初始化數(shù)據(jù)庫(kù)、修改密碼等步驟,同時(shí)還介紹了如何下載和安裝SQLyog圖形化工具,以便更方便地管理和操作MySQL數(shù)據(jù)庫(kù),需要的朋友可以參考下
    2025-11-11

最新評(píng)論

鄂托克旗| 册亨县| 湾仔区| 茂名市| 克拉玛依市| 岱山县| 五寨县| 金川县| 三原县| 澄城县| 乌拉特后旗| 岳池县| 嵊州市| 文山县| 富阳市| 南江县| 墨江| 商洛市| 静安区| 定西市| 敦化市| 杭锦后旗| 吴旗县| 东阳市| 手机| 金门县| 运城市| 禹城市| 广州市| 阜新| 江山市| 沈丘县| 汝南县| 南和县| 镶黄旗| 赞皇县| 福贡县| 罗田县| 磐安县| 南阳市| 汶川县|