日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

深入分析mysql為什么不推薦使用uuid或者雪花id作為主鍵

瀏覽:84日期:2023-10-11 16:50:26

前言:在mysql中設(shè)計表的時候,mysql官方推薦不要使用uuid或者不連續(xù)不重復(fù)的雪花id(long形且唯一),而是推薦連續(xù)自增的主鍵id,官方的推薦是auto_increment,那么為什么不建議采用uuid,使用uuid究竟有什么壞處?本篇博客我們就來分析這個問題,探討一下內(nèi)部的原因。

一:mysql和程序?qū)嵗?/b>

1.1:要說明這個問題,我們首先來建立三張表,分別是user_auto_key,user_uuid,user_random_key,分別表示自動增長的主鍵,uuid作為主鍵,隨機(jī)key作為主鍵,其它我們完全保持不變.根據(jù)控制變量法,我們只把每個表的主鍵使用不同的策略生成,而其他的字段完全一樣,然后測試一下表的插入速度和查詢速度:

注:這里的隨機(jī)key其實是指用雪花算法算出來的前后不連續(xù)不重復(fù)無規(guī)律的id:一串18位長度的long值

id自動生成表:

深入分析mysql為什么不推薦使用uuid或者雪花id作為主鍵

用戶uuid表

深入分析mysql為什么不推薦使用uuid或者雪花id作為主鍵

隨機(jī)主鍵表:

深入分析mysql為什么不推薦使用uuid或者雪花id作為主鍵

1.2:光有理論不行,直接上程序,使用spring的jdbcTemplate來實現(xiàn)增查測試:

技術(shù)框架:springboot+jdbcTemplate+junit+hutool,程序的原理就是連接自己的測試數(shù)據(jù)庫,然后在相同的環(huán)境下寫入同等數(shù)量的數(shù)據(jù),來分析一下insert插入的時間來進(jìn)行綜合其效率,為了做到最真實的效果,所有的數(shù)據(jù)采用隨機(jī)生成,比如名字、郵箱、地址都是隨機(jī)生成,程序已上傳自gitee,地址在文底。

package com.wyq.mysqldemo;import cn.hutool.core.collection.CollectionUtil;import com.wyq.mysqldemo.databaseobject.UserKeyAuto;import com.wyq.mysqldemo.databaseobject.UserKeyRandom;import com.wyq.mysqldemo.databaseobject.UserKeyUUID;import com.wyq.mysqldemo.diffkeytest.AutoKeyTableService;import com.wyq.mysqldemo.diffkeytest.RandomKeyTableService;import com.wyq.mysqldemo.diffkeytest.UUIDKeyTableService;import com.wyq.mysqldemo.util.JdbcTemplateService;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.util.StopWatch;import java.util.List;@SpringBootTestclass MysqlDemoApplicationTests { @Autowired private JdbcTemplateService jdbcTemplateService; @Autowired private AutoKeyTableService autoKeyTableService; @Autowired private UUIDKeyTableService uuidKeyTableService; @Autowired private RandomKeyTableService randomKeyTableService; @Test void testDBTime() { StopWatch stopwatch = new StopWatch('執(zhí)行sql時間消耗'); /** * auto_increment key任務(wù) */ final String insertSql = 'INSERT INTO user_key_auto(user_id,user_name,sex,address,city,email,state) VALUES(?,?,?,?,?,?,?)'; List<UserKeyAuto> insertData = autoKeyTableService.getInsertData(); stopwatch.start('自動生成key表任務(wù)開始'); long start1 = System.currentTimeMillis(); if (CollectionUtil.isNotEmpty(insertData)) { boolean insertResult = jdbcTemplateService.insert(insertSql, insertData, false); System.out.println(insertResult); } long end1 = System.currentTimeMillis(); System.out.println('auto key消耗的時間:' + (end1 - start1)); stopwatch.stop(); /** * uudID的key */ final String insertSql2 = 'INSERT INTO user_uuid(id,user_id,user_name,sex,address,city,email,state) VALUES(?,?,?,?,?,?,?,?)'; List<UserKeyUUID> insertData2 = uuidKeyTableService.getInsertData(); stopwatch.start('UUID的key表任務(wù)開始'); long begin = System.currentTimeMillis(); if (CollectionUtil.isNotEmpty(insertData)) { boolean insertResult = jdbcTemplateService.insert(insertSql2, insertData2, true); System.out.println(insertResult); } long over = System.currentTimeMillis(); System.out.println('UUID key消耗的時間:' + (over - begin)); stopwatch.stop(); /** * 隨機(jī)的long值key */ final String insertSql3 = 'INSERT INTO user_random_key(id,user_id,user_name,sex,address,city,email,state) VALUES(?,?,?,?,?,?,?,?)'; List<UserKeyRandom> insertData3 = randomKeyTableService.getInsertData(); stopwatch.start('隨機(jī)的long值key表任務(wù)開始'); Long start = System.currentTimeMillis(); if (CollectionUtil.isNotEmpty(insertData)) { boolean insertResult = jdbcTemplateService.insert(insertSql3, insertData3, true); System.out.println(insertResult); } Long end = System.currentTimeMillis(); System.out.println('隨機(jī)key任務(wù)消耗時間:' + (end - start)); stopwatch.stop(); String result = stopwatch.prettyPrint(); System.out.println(result); }

1.3:程序?qū)懭虢Y(jié)果

user_key_auto寫入結(jié)果:

深入分析mysql為什么不推薦使用uuid或者雪花id作為主鍵

user_random_key寫入結(jié)果:

深入分析mysql為什么不推薦使用uuid或者雪花id作為主鍵

user_uuid表寫入結(jié)果:

深入分析mysql為什么不推薦使用uuid或者雪花id作為主鍵

1.4:效率測試結(jié)果

深入分析mysql為什么不推薦使用uuid或者雪花id作為主鍵

在已有數(shù)據(jù)量為130W的時候:我們再來測試一下插入10w數(shù)據(jù),看看會有什么結(jié)果:

深入分析mysql為什么不推薦使用uuid或者雪花id作為主鍵

可以看出在數(shù)據(jù)量100W左右的時候,uuid的插入效率墊底,并且在后序增加了130W的數(shù)據(jù),uudi的時間又直線下降。時間占用量總體可以打出的效率排名為:auto_key>random_key>uuid,uuid的效率最低,在數(shù)據(jù)量較大的情況下,效率直線下滑。那么為什么會出現(xiàn)這樣的現(xiàn)象呢?帶著疑問,我們來探討一下這個問題:

二:使用uuid和自增id的索引結(jié)構(gòu)對比

2.1:使用自增id的內(nèi)部結(jié)構(gòu)

深入分析mysql為什么不推薦使用uuid或者雪花id作為主鍵

自增的主鍵的值是順序的,所以Innodb把每一條記錄都存儲在一條記錄的后面。當(dāng)達(dá)到頁面的最大填充因子時候(innodb默認(rèn)的最大填充因子是頁大小的15/16,會留出1/16的空間留作以后的 修改):

①下一條記錄就會寫入新的頁中,一旦數(shù)據(jù)按照這種順序的方式加載,主鍵頁就會近乎于順序的記錄填滿,提升了頁面的最大填充率,不會有頁的浪費

②新插入的行一定會在原有的最大數(shù)據(jù)行下一行,mysql定位和尋址很快,不會為計算新行的位置而做出額外的消耗

③減少了頁分裂和碎片的產(chǎn)生

2.2:使用uuid的索引內(nèi)部結(jié)構(gòu)

深入分析mysql為什么不推薦使用uuid或者雪花id作為主鍵

因為uuid相對順序的自增id來說是毫無規(guī)律可言的,新行的值不一定要比之前的主鍵的值要大,所以innodb無法做到總是把新行插入到索引的最后,而是需要為新行尋找新的合適的位置從而來分配新的空間。這個過程需要做很多額外的操作,數(shù)據(jù)的毫無順序會導(dǎo)致數(shù)據(jù)分布散亂,將會導(dǎo)致以下的問題:

①:寫入的目標(biāo)頁很可能已經(jīng)刷新到磁盤上并且從緩存上移除,或者還沒有被加載到緩存中,innodb在插入之前不得不先找到并從磁盤讀取目標(biāo)頁到內(nèi)存中,這將導(dǎo)致大量的隨機(jī)IO

②:因為寫入是亂序的,innodb不得不頻繁的做頁分裂操作,以便為新的行分配空間,頁分裂導(dǎo)致移動大量的數(shù)據(jù),一次插入最少需要修改三個頁以上

③:由于頻繁的頁分裂,頁會變得稀疏并被不規(guī)則的填充,最終會導(dǎo)致數(shù)據(jù)會有碎片

在把隨機(jī)值(uuid和雪花id)載入到聚簇索引(innodb默認(rèn)的索引類型)以后,有時候會需要做一次OPTIMEIZE TABLE來重建表并優(yōu)化頁的填充,這將又需要一定的時間消耗。

結(jié)論:使用innodb應(yīng)該盡可能的按主鍵的自增順序插入,并且盡可能使用單調(diào)的增加的聚簇鍵的值來插入新行

2.3:使用自增id的缺點

那么使用自增的id就完全沒有壞處了嗎?并不是,自增id也會存在以下幾點問題:

①:別人一旦爬取你的數(shù)據(jù)庫,就可以根據(jù)數(shù)據(jù)庫的自增id獲取到你的業(yè)務(wù)增長信息,很容易分析出你的經(jīng)營情況

②:對于高并發(fā)的負(fù)載,innodb在按主鍵進(jìn)行插入的時候會造成明顯的鎖爭用,主鍵的上界會成為爭搶的熱點,因為所有的插入都發(fā)生在這里,并發(fā)插入會導(dǎo)致間隙鎖競爭

③:Auto_Increment鎖機(jī)制會造成自增鎖的搶奪,有一定的性能損失

附:Auto_increment的鎖爭搶問題,如果要改善需要調(diào)優(yōu)innodb_autoinc_lock_mode的配置

三:總結(jié)

本篇博客首先從開篇的提出問題,建表到使用jdbcTemplate去測試不同id的生成策略在大數(shù)據(jù)量的數(shù)據(jù)插入表現(xiàn),然后分析了id的機(jī)制不同在mysql的索引結(jié)構(gòu)以及優(yōu)缺點,深入的解釋了為何uuid和隨機(jī)不重復(fù)id在數(shù)據(jù)插入中的性能損耗,詳細(xì)的解釋了這個問題。在實際的開發(fā)中還是根據(jù)mysql的官方推薦最好使用自增id,mysql博大精深,內(nèi)部還有很多值得優(yōu)化的點需要我們學(xué)習(xí)。

附:本篇博客demo地址:https://gitee.com/Yrion/mysqlIdDemo

到此這篇關(guān)于深入分析mysql為什么不推薦使用uuid或者雪花id作為主鍵的文章就介紹到這了,更多相關(guān)mysql uuid或者雪花id作為主鍵內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: MySQL 數(shù)據(jù)庫
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
jizzjizz中国精品麻豆| 日本成人中文字幕| 日韩福利视频一区| 蜜臀久久久久久久| 亚洲一区欧美二区| 免费在线视频一区| 日本欧洲一区二区| 亚洲理论在线| 国产欧美一区二区三区精品观看| 亚洲人成在线影院| 亚洲激情久久| 亚洲激情精品| 黄色日韩在线| 丝袜美腿一区二区三区| 日韩中文av| 国产精品www.| 久久一区国产| 日韩精品一区二区三区免费观看| 精品国产亚洲日本| 黑人精品一区| 中文欧美日韩| 国产亚洲电影| 激情黄产视频在线免费观看| 青青久久av| 91久久视频| 欧美另类专区| 日韩国产欧美在线视频| 久久精品福利| 国产伊人久久| 久久久久久色 | 欧美伊人影院| 麻豆中文一区二区| 免费观看久久av| 色天使综合视频| 亚洲精品一二三**| 亚洲www免费| 欧美不卡高清| 日本少妇一区二区| 久久精品国内一区二区三区水蜜桃| 欧美日韩中文一区二区| 久久国产精品毛片| 国产精品地址| 性欧美xxxx免费岛国不卡电影| 免费观看在线综合| 国产精品sss在线观看av| 毛片在线网站| 欧美久久精品一级c片| 免费在线观看一区二区三区| 欧美日韩视频| 国产精品视频一区二区三区| 欧美精品羞羞答答| 日本不卡一区二区三区| 四虎884aa成人精品最新| 日韩精品福利一区二区三区| 精品视频自拍| 首页国产欧美久久| 久久婷婷国产| 国产精品99一区二区| 日韩精品一级中文字幕精品视频免费观看 | 欧美黄色一区二区| 日韩一区二区三区免费播放| 亚洲综合精品| 久久精品国内一区二区三区| 久久99久久久精品欧美| 久久国产日韩| 久久亚洲美女| 亚洲理论在线| 在线视频精品| 中国字幕a在线看韩国电影| 欧美天堂一区二区| 免费美女久久99| 欧美福利在线| av一区在线| av高清不卡| 日韩精品一区二区三区av| 欧美亚洲国产一区| 国产一区国产二区国产三区| 日韩精品免费视频一区二区三区| 女人天堂亚洲aⅴ在线观看| 日韩精品专区| 精品一区不卡| 国产欧美日韩一区二区三区四区| 国产精品普通话对白| 极品日韩av| 日韩黄色大片| 久久影院午夜精品| 国产精品最新自拍| 亚洲欧美一级| 亚洲欧美不卡| 亚洲激情国产| 视频一区日韩| 日韩一区二区三免费高清在线观看 | 欧美精品三级在线| 日韩在线观看| 亚洲天堂一区二区| 国产精品黑丝在线播放| 麻豆免费精品视频| 麻豆国产91在线播放| 久久精品一区二区三区中文字幕| 亚洲综合三区| 蜜臀av亚洲一区中文字幕| 亚洲专区一区| 在线国产日韩| 亚洲精品国产精品粉嫩| 欧美日韩xxxx| 精品中文字幕一区二区三区四区| 国产精品中文字幕亚洲欧美| 日韩国产在线观看一区| 欧美影院精品| 美女视频黄免费的久久| 91精品国产自产观看在线 | 日韩综合精品| 国产欧美日韩一区二区三区四区 | 国产一区一一区高清不卡| 精品国产不卡| 国产一区二区三区久久| 麻豆国产精品| 精品国产一级| 国产精品专区免费| 国产精品s色| 国产精品永久| 成人国产综合| 日韩欧美少妇| 久久亚洲风情| 国产日韩欧美一区| 韩日一区二区| 日韩欧美看国产| 日韩精品欧美| 免费久久99精品国产| 日韩国产欧美视频| 国产精品一线天粉嫩av| 精品一区二区男人吃奶| 欧美aⅴ一区二区三区视频| 电影91久久久| 欧美成人精品午夜一区二区| 欧美日本三区| 成人福利视频| 亚洲欧美日韩国产一区二区| 最新日韩欧美| 欧美日韩18| 国产精品99久久免费观看| 国产高清亚洲| 国产一区二区三区不卡视频网站| 国产精品91一区二区三区| 午夜欧美精品久久久久久久| 欧美日韩精品一区二区三区视频 | 久久久久久久欧美精品| 免费精品视频最新在线| 日本vs亚洲vs韩国一区三区二区| 国产欧美一区二区色老头| 99视频精品全国免费| 午夜在线精品偷拍| 国产精品亚洲欧美一级在线| 日韩精品网站| 日韩在线观看一区二区三区| 国产一区二区亚洲| 快she精品国产999| 国产日韩中文在线中文字幕 | 红桃视频国产精品| 国产精品午夜一区二区三区| 国产激情一区| 婷婷亚洲五月| 欧美成人精品一级| 久久国产66| a天堂资源在线| 国产亚洲电影| 99精品99| 97人人精品| 88久久精品| 99视频一区| 日本午夜大片a在线观看| 国产麻豆精品| 免费国产自久久久久三四区久久| 成人亚洲一区二区| 免费成人在线观看| 国产精品亲子伦av一区二区三区| 亚洲国产日韩欧美在线| 精品国产黄a∨片高清在线| 日韩中文字幕| 午夜亚洲一区| 日韩毛片视频| 精品国产鲁一鲁****| 青青草91视频| 三级欧美韩日大片在线看| 国产一区亚洲| 精品国产精品久久一区免费式 | 亚洲天堂久久| 国产一区2区| 老色鬼久久亚洲一区二区| 日韩伦理一区| 精品一区二区三区在线观看视频| 亚洲精品免费观看| 国产亚洲精品自拍| 欧美亚洲在线日韩| 国产不卡人人| 国产一区二区精品久| 国产精品对白久久久久粗| 日本精品在线播放| 久久av一区| 性欧美精品高清|