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

Mysql大表全表update的的實現

 更新時間:2024年08月20日 10:07:00   作者:最愛彩虹糖  
有些時候在進行一些業(yè)務迭代時需要我們對Mysql表中數據進行全表update,本文主要介紹了Mysql大表update的的實現

前言

有些時候在進行一些業(yè)務迭代時需要我們對Mysql表中數據進行全表update,如果是在數據量比較小的情況下(萬級別),可以直接執(zhí)行sql語句,但是如果數據量達到一個量級后,就會出現一些問題,比如主從架構部署的Mysql,主從同步需要需要binlog來完成,而binlog格式如下,其中使用statement和row格式的主從同步之間binlog在update情況下的展示:

格式內容
statement記錄同步在主庫上執(zhí)行的每一條sql,日志量較少,減少io,但是部分函數sql會出現問題比如random
row記錄每一條數據被修改或者刪除的詳情,日志量在特定條件下很大,如批量delete、update
mixed以上兩種方式混用,一般的語句修改使用statement記錄,其他函數式使用row

在這里插入圖片描述

我們當前線上mysql是使用row格式binlog來進行的主從同步,因此如果在億級數據的表中執(zhí)行全表update,必然會在主庫中產生大量的binlog,接著會在進行主從同步時,從庫也需要阻塞執(zhí)行大量sql,風險極高,因此直接update是不行的。本文就從我最開始的一個全表update sql開始,到最后上線的分批更新策略,如何優(yōu)化和思考來展開說明。

正文

直接update的問題

我們前段時間需要將用戶的一些基本信息存儲從http轉換為https,庫中數據大概在幾千w的級別,需要對一些大表進行全表update,最開始我試探性的跟dba同事拋出了一個簡單的update語句,想著流量低的時候執(zhí)行,如下:

update tb_user_info set user_img=replace(user_img,'http://','https://')

深度分頁問題

上面肯定是不合理的會給主庫生成binlog、從庫接收binlog寫數據帶來很大的壓力,于是就想使用腳本分批處理如下所示: 寫一個這樣的腳本,依次分批替換,limit的游標不斷增加。大概一看是沒有問題的,但是仔細一想mysql的limit游標進行的范圍查找原理,是下沉到B+數的葉子節(jié)點進行的向后遍歷查找,在limit數據比較小的情況下還好,limit數據量比較大的情況下,效率很低接近于全表掃描,這也就是我們常說的“深度分頁問題”。

update tb_user_info set user_img=replace(user_img,'http://','https://') limit 1,1000;

in的效率

既然mysql的深分頁有問題,那么我就把這批id全部查出來,然后更新的id in這些列表,進行批量更新可以嗎?于是我又寫了類似下面sql的腳本。結果是還不行,雖然mysql對于in這些查找有一些鍵值預測,但是仍然是很低效。

select * from tb_user_info where id> {index} limit 100;
update tb_user_info set user_img=replace(user_img,'http','https')where id in {id1,id3,id2};

最終版本

最終在與dba的多次溝通下,我們寫了如下的sql及腳本,這里有幾個問題需要注意,我們在select sql中使用了這個語法/*!40001 SQL_NO_CACHE */,這個語法的意思就是本次查詢不使用innodb的buffer pool,也不會將本次查詢的數據頁放到buffer pool中作為熱點數據的緩存。接著對于查詢強制使用主鍵索引FORCE INDEX(PRIMARY),并且根據主鍵索引排序,排序后的數據進行id游標的篩選。最后執(zhí)行update更新時,由于我們在前面的sql中查詢到的就是已經排序后的主鍵,因此可以對id執(zhí)行范圍查找。

select /*!40001 SQL_NO_CACHE */ id from tb_user_info FORCE INDEX(`PRIMARY`) where id> "1" ORDER BY id limit 1000,1;
update tb_user_info set user_img=replace(user_img,'http','https') where id >"{1}" and id <"{2}";

我們可以僅關注第一個sql,如下圖所示,是buffer pool大概內容,我們可以通過這個no cache的關鍵字,對批量處理的數據進行強制指定不走buffer pool,不把這些冷數據影響到正常使用的緩存內容,防止效率的降低,其實mysql在一些備份的動作中。使用的數據掃描sql也會帶上這個關鍵字,防止影響到正常的業(yè)務緩存;接著需要強制對當前查詢指定的主鍵索引,然后進行排序,否則mysql有可能在計算io成本進行索引選擇時,選擇其他的索引。

在這里插入圖片描述

使用這樣的方式對數據庫進行批量更新可以通過一個接口來控制速率,對于數據庫主從同步、iops、內存使用率等關鍵屬性進行觀察,手動調整刷庫速率。這樣看是單線程阻塞的操作,其實接口也可以定義線程個數等屬性,接口中根據賦予的線程個數,通過線程池并行刷數據,從而提高全表更新速率的上限,同時對速率進行控制控制。

其他問題

如果我們使用snowflake雪花算法或者自增主鍵來生成主鍵id的話,插入的記錄都是根據主鍵id順序插入的,如果使用uuid這種我們怎么處理?當然是業(yè)務中就預先處理了,先把入庫的數據提前進行替換,進行代碼上線后再進行的全量數據更新了。

結語

刷數據本來是一個異常枯燥的工作內容,但是從這次數據量較大的數據更新從而與dba同事的多次溝通后,也對mysql有了一些新的理解,包括不限于下面幾個,共同學習。

  • binlog格式帶來的大數據量更新的主從同步問題;
  • Mysql深分頁的效率問題;
  • 全表掃數據如何防止對buffer pool污染到我們業(yè)務正常的熱點數據。

到此這篇關于Mysql大表update的的實現的文章就介紹到這了,更多相關Mysql大表update內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家! 

相關文章

  • MySQL btree索引與hash索引區(qū)別

    MySQL btree索引與hash索引區(qū)別

    這篇文章主要介紹了MySQL btree索引與hash索引區(qū)別,幫助大家更好的理解和學習MySQL索引的相關知識,感興趣的朋友可以了解下
    2020-09-09
  • mysql配置模板(my-*.cnf)參數詳細說明

    mysql配置模板(my-*.cnf)參數詳細說明

    這篇文章主要介紹了mysql配置模板就是mysql的配置文件參數說明,需要的朋友可以參考下
    2015-01-01
  • SQL面試題:求時間差之和(有重復不計)

    SQL面試題:求時間差之和(有重復不計)

    這篇文章主要介紹了SQL面試題:求時間差之和(有重復不計),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-11-11
  • mysql實現向下遞歸與向上遞歸方式

    mysql實現向下遞歸與向上遞歸方式

    本文介紹了FIND_IN_SET函數的使用,可以替代SQL的IN查詢多個節(jié)點數據,也可通過=關聯(lián)查詢單個節(jié)點,此外,還提到了向下和向上遞歸查詢的方法
    2026-04-04
  • 解決MySQL啟動常見錯誤:ERROR 2002(HY000) Can‘t connect to local MySQL server through socket‘tmp問題

    解決MySQL啟動常見錯誤:ERROR 2002(HY000) Can‘t connect

    這篇文章主要介紹了解決MySQL啟動常見錯誤:ERROR 2002(HY000) Can‘t connect to local MySQL server through socket‘tmp問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • Mysql應用安裝后找不到my.ini文件的解決過程

    Mysql應用安裝后找不到my.ini文件的解決過程

    剛剛在修改mysql默認配置的時候,發(fā)現找不到my.ini文件,下面這篇文章主要給大家介紹了關于Mysql應用安裝后找不到my.ini文件的解決過程,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2022-08-08
  • 淺談mysql雙層not exists查詢執(zhí)行流程

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

    本文主要介紹了淺談mysql雙層not?exists查詢執(zhí)行流程,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-06-06
  • mysql 字段as詳解及實例代碼

    mysql 字段as詳解及實例代碼

    這篇文章主要介紹了mysql 字段as詳解,并附實例代碼的相關資料,需要的朋友可以參考下
    2016-09-09
  • MySQL asc、desc數據排序的實現

    MySQL asc、desc數據排序的實現

    這篇文章主要介紹了MySQL asc、desc數據排序的實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-12-12
  • Linux服務器中MySQL遠程連接的開啟方法

    Linux服務器中MySQL遠程連接的開啟方法

    今天在Linux服務器上安裝了msyql數據庫,在本地訪問的時候可以訪問,但是我想通過遠程的方式訪問的時候就不能訪問了,查詢資料后發(fā)現,Linux下MySQL默認安裝完成后只有本地訪問的權限,沒有遠程訪問的權限,需要你給指定用戶設置訪問權限才能遠程訪問該數據庫
    2017-06-06

最新評論

昭苏县| 上犹县| 望奎县| 黄冈市| 高雄市| 普宁市| 罗平县| 兴化市| 久治县| 平塘县| 镇远县| 巩义市| 宜兰县| 大庆市| 建平县| 永胜县| 乌拉特前旗| 兖州市| 普兰店市| 安塞县| 上饶县| 浦县| 铁岭市| 松阳县| 昆明市| 托克逊县| 崇左市| 阳高县| 和林格尔县| 同德县| 修水县| 汪清县| 昌平区| 莎车县| 读书| 北票市| 乌什县| 镇坪县| 神农架林区| 凤城市| 黔西县|