偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

MySQL:為什么說應(yīng)該優(yōu)先選擇普通索引,盡量避免使用唯一索引

數(shù)據(jù)庫(kù) MySQL
今天我們來聊一聊,普通索引和唯一索引的使用場(chǎng)景,以及為什么說推薦大家優(yōu)先使用普通索引,盡量避免使用唯一索引。

前言

在使用MySQL的過程中,隨著表數(shù)據(jù)的逐漸增多,為了更快的查詢我們需要的數(shù)據(jù),我們會(huì)在表中建立不同類型的索引。

今天我們來聊一聊,普通索引和唯一索引的使用場(chǎng)景,以及為什么說推薦大家優(yōu)先使用普通索引,盡量避免使用唯一索引。

對(duì)于一個(gè)普通的二級(jí)索引,目的就是為了加速查詢,所以我們可能會(huì)為表中的某個(gè)字段或者某些字段,建立一個(gè)普通的二級(jí)索引。

而對(duì)于唯一索引來說,由于其唯一鍵約束的特性,有時(shí)我們會(huì)更多的賦予其業(yè)務(wù)含義。比如有一張存儲(chǔ)身份證號(hào)的表,為了保證身份證號(hào)的唯一性,我們會(huì)在身份證號(hào)字段上建立唯一索引。

那為什么說,不推薦大家使用唯一索引呢?

接下來,我們從查詢和更新兩方面分析一下唯一索引和普通索引的性能差距。

查詢性能

我們知道每個(gè)索引其實(shí)都是一棵二叉樹,所以我簡(jiǎn)單畫了一個(gè)索引圖,不太好看,大家多多擔(dān)待。

給大家稍微解釋一下這張圖,不同顏色代表不同的數(shù)據(jù)頁(yè),這里假設(shè)一個(gè)數(shù)據(jù)頁(yè)里面存放兩條數(shù)據(jù)。

我們知道MySQL磁盤與內(nèi)存交互是通過一個(gè)叫做數(shù)據(jù)頁(yè)的單位,每個(gè)數(shù)據(jù)頁(yè)默認(rèn)的大小是16K。

在一棵樹上,只有葉子節(jié)點(diǎn)才會(huì)真正的存放數(shù)據(jù),非葉子節(jié)點(diǎn)存放的是每個(gè)下級(jí)數(shù)據(jù)頁(yè)中最小的索引字段以及指向下級(jí)數(shù)據(jù)頁(yè)的指針。

對(duì)于主鍵索引,葉子節(jié)點(diǎn)存放的是一行真正的數(shù)據(jù),而對(duì)于二級(jí)索引來說,在葉子節(jié)點(diǎn)存儲(chǔ)的是索引字段以及對(duì)應(yīng)的主鍵id。

好了,下面我們分析一下,普通二級(jí)索引和唯一索引是如何查數(shù)據(jù)的?

以一個(gè)簡(jiǎn)單的查詢sql為例:select id from t where m=103;

1,MySQL從根節(jié)點(diǎn)出發(fā),通過二分法判斷m=103大于100小于104,所以會(huì)找到根節(jié)點(diǎn)中100對(duì)應(yīng)的數(shù)據(jù)頁(yè)100-102;

2,在100-102的數(shù)據(jù)頁(yè)上,由于103大于102,所以會(huì)找到102對(duì)應(yīng)的102-103的數(shù)據(jù)頁(yè);

3,在這個(gè)數(shù)據(jù)頁(yè)上,找到了m=103的記錄,并獲取到了要查詢的id字段。

對(duì)于普通的二級(jí)索引來說,找到第一條m=103的記錄之后,會(huì)繼續(xù)向后查找,在104-105這個(gè)數(shù)據(jù)頁(yè)中判斷是否還有符合m=103條件的記錄,如果沒有則結(jié)束查詢。

而對(duì)于唯一索引來說,由于其唯一性約束,所以在查找到第一條記錄之后,就結(jié)束了查找。

可以看到,二者的差別就在于是否繼續(xù)查到下一條。

那這兩者有多大的性能差距呢?答案是幾乎沒有。

我們知道,MySQL的數(shù)據(jù)是以頁(yè)為單位存放的,以一個(gè)int類型的二級(jí)索引為例,一個(gè)int占4個(gè)字節(jié),加上MySQL的頭信息6個(gè)字節(jié),相當(dāng)于10個(gè)字節(jié)。

那么一個(gè)16k的頁(yè)上能存放多少記錄呢?

16*1024/10 = 1638。也就是說,一個(gè)數(shù)據(jù)頁(yè)就可能放下1600多條記錄。那么我們?cè)诓樵償?shù)據(jù)時(shí),會(huì)把整個(gè)數(shù)據(jù)頁(yè)都加載進(jìn)內(nèi)存,此時(shí)對(duì)于普通二級(jí)索引判斷下一個(gè)記錄的操作所需的消耗是非常非常小的。

可以說,從查詢方面來看,普通二級(jí)索引和唯一索引的性能基本是相當(dāng)?shù)摹?/span>

更新性能

唯一索引和普通二級(jí)索引的性能差距主要體現(xiàn)在更新操作上。

對(duì)于MySQL來說,更新一條語句的邏輯是首先讀到要更新的記錄,如果這個(gè)記錄沒有在內(nèi)存里,就先加載到內(nèi)存。然后執(zhí)行更新的語句,之后再把變更的數(shù)據(jù)刷新到磁盤中。

但是,對(duì)于MySQL來說,把數(shù)據(jù)從磁盤讀到內(nèi)存涉及到隨機(jī)IO,是成本非常高的一種操作。

如果每次更新數(shù)據(jù)都要這么來一次的話,高性能這個(gè)指標(biāo)恐怕很難保證。

所以,設(shè)計(jì)MySQL的大神們引入了一個(gè)叫做change buffer的東西。

change buffer是一種可以持久化的緩存數(shù)據(jù),當(dāng)我們要更新數(shù)據(jù)時(shí),如果要更新的數(shù)據(jù)不存在于內(nèi)存,此時(shí)并不需要把數(shù)據(jù)從磁盤加載到內(nèi)存,而是將更新操作記錄在change buffer中,更新操作就算完成了。

當(dāng)下次要讀取這些數(shù)據(jù)時(shí),會(huì)把讀到的數(shù)據(jù)和change buffer進(jìn)行合并,或者叫merge。

通過change buffer,更新操作就不需要去讀磁盤了,全程都是內(nèi)存操作,性能自然可以得到極大的提升。

但是!但是問題又來了!

change buffer只對(duì)普通二級(jí)索引有效,對(duì)于唯一索引是沒有效果的。

為什么呢?

因?yàn)樵诟乱粭l記錄時(shí),我們需要檢查索引的唯一性約束。

如何檢查呢?自然首先要把數(shù)據(jù)從磁盤加載到內(nèi)存里面才能進(jìn)行判斷。

可是如果都已經(jīng)把數(shù)據(jù)加載到內(nèi)存里,再去使用change buffer不就顯得多此一舉了。

所以,唯一索引不能,也沒必要去使用change buffer來提升性能了。

由于對(duì)唯一索引的更新涉及到讀磁盤這個(gè)隨機(jī)IO操作,性能自然也是比不上普通二級(jí)索引了,這就是推薦大家優(yōu)先使用普通二級(jí)索引的原因了。

經(jīng)過對(duì)比,大家也可以看到,這兩種索引在查詢上性能基本是一致的,其性能差距主要體現(xiàn)在更新操作上。

其實(shí)即便是大家有一些特殊的業(yè)務(wù)需要,比如存放唯一的身份證號(hào)等,還是建議大家通過業(yè)務(wù)層去約束。

總的來說,普通的二級(jí)索引比唯一索引帶來的收益要更大。

責(zé)任編輯:姜華 來源: 今日頭條
相關(guān)推薦

2012-07-13 13:51:57

AndroidiOS

2022-01-27 11:02:04

索引數(shù)據(jù)存儲(chǔ)

2021-09-06 06:45:06

普通索引唯一

2024-03-25 10:00:00

C++編程else

2022-08-04 08:22:49

MySQL索引

2022-03-28 08:24:52

MySQL聚簇索引非聚簇索引

2016-03-24 09:53:24

swiftguardios

2021-06-06 13:03:53

MySQL普通索引

2021-05-26 09:27:22

物聯(lián)網(wǎng)人工智能AIoT

2021-02-03 08:52:52

Mysql索引數(shù)據(jù)庫(kù)

2021-09-23 22:16:04

程序員IT互聯(lián)網(wǎng)

2013-06-25 09:29:46

OpenStackAmazon S3云存儲(chǔ)

2020-02-12 19:01:22

索引B-樹B+樹

2020-08-10 11:20:59

索引MySQL數(shù)據(jù)庫(kù)

2024-05-22 09:01:53

InnoDBB+索引

2010-06-11 17:13:34

MySQL表索引

2021-05-13 07:58:06

UDP協(xié)議HTTP

2024-05-24 09:29:28

2021-12-13 01:40:29

ElasticSear倒排索引

2016-10-21 14:17:01

云服務(wù)云優(yōu)先策略
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)