目錄
引言
情景再現
發現問題
解決問題
首頁 後端開發 php教程 記一次MYSQL更新優化

記一次MYSQL更新優化

Aug 08, 2016 am 09:19 AM
id select where

引言

今天(August 5, 2015 5:34 PM)在給數據庫中一張表的結構做一次調整,添加了幾個字段,後面對之前的數據進行刷新,刷新的內容是:對其中的一個已有欄位url進行匹配,然後更新新加的欄位typetypeid。後來我寫了個shell腳本來刷數據,結果運行shell腳本後我就懵了,怎麼這麼慢~~~

情景再現

<code>CREATE TABLE `fuckSpeed` (
  `uin` bigint(20) unsigned NOT NULL DEFAULT 0,
  `id` int(11) unsigned NOT NULL DEFAULT 0,
  `url` varchar(255) NOT NULL DEFAULT '',
  `type` int(11) unsigned NOT NULL DEFAULT 0,
  `typeid` varchar(64) NOT NULL DEFAULT '',
  ......
  KEY `uin_id` (`uin`,`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;</code>
登入後複製

表結構大概是上面這樣的(省略了好多字段),表中只有一個聯合索引uin_id,而我在更新的時候是下面的思路:

  • 首先根據一個id範圍獲取到一定數量的數據
    select id,url from funkSpeed where id>=101 and id
  • 遍歷所有的數據,對每一條數據進行更新
    #首先對數據進行處理,匹配獲取type和typeid
    update fuckSpeed set type=[type],typeid=[typeid] where id=[id]
    按照上面的思路搞了之後,發現更新特別的慢,平均每秒鐘3~5個左右,我也是醉了,我看看要更新的數據,總共有32w+條,這樣更新下來大概需要24h+,也就是1天還要多,額~~哭了,想想一定是哪裡出問題了。

發現問題

首先我想到的是不是因為只有一個進程在更新,導致很慢,我啟動了5個進程,將id分段了,就像下面這樣

<code>./update_url.sh 0 10000 &
./update_url.sh 10000 20001 &
./update_url.sh 20001 30001 &
./update_url.sh 30002 40002 &
./update_url.sh 40003 50003 &</code>
登入後複製

運行之後發現還是那樣,速度沒有提升多少,還是每秒鐘更新3~5個左右,想想也是啊,時間不可能花費在插入資料之前的那些步驟(匹配、組裝sql語句、。。。),應該是插入的時候有問題

再來看看我的sql語句select id,url from funkSpeed where id>=101 and id,這裡,試著在命令列執行了下,結果如下

<code>mysql> select id,url from funkSpeed where id>=0 and id<=200;
Empty set (0.18 sec)</code>
登入後複製

竟然花了0.18秒,這時候我猜恍然大悟,聯合索引我沒有使用到,聯合索引生效的條件是--必須要有左邊的字段,用explain驗證下,果然是這樣:

<code>mysql> explain id,url from funkSpeed where id>=0 and id<=200;
+-------------+------+---------------+------+---------+------+--------+-------------+
| table       | type | possible_keys | key  | key_len | ref  | rows   | Extra       |
+-------------+------+---------------+------+---------+------+--------+-------------+
| funkSpeed 	 | ALL  | NULL          | NULL | NULL    | NULL | 324746 | Using where |
+-------------+------+---------------+------+---------+------+--------+-------------+
1 row in set (0.00 sec)</code>
登入後複製

然後使用聯合索引:

<code>mysql> select uin,id from funkSpeed where uin=10023 and id=162;
+------------+----------+
| uin        |   id     |
+------------+----------+
| 10023      | 162      |
+------------+----------+
1 row in set (0.00 sec)

mysql> explain select uin,id from funkSpeed where uin=10023 and id=162;
+-------------+------+---------------+----------+---------+-------------+------+-------------+
| table       | type | possible_keys | key      | key_len | ref         | rows | Extra       |
+-------------+------+---------------+----------+---------+-------------+------+-------------+
| funkSpeed   | ref  | uin_id        | uin_id   | 12      | const,const |    4 | Using index |
+-------------+------+---------------+----------+---------+-------------+------+-------------+
1 row in set (0.00 sec)</code>
登入後複製

可以看到幾乎是秒查,這個時候基本上可以斷定問題是出現在索引這個地方了

我select的時候次數比較少,每兩個select之間id相差10000,所以這裡可以忽略掉,而且這裡沒辦法優化,除非在id上面加上索引。

問題發生在update fuckSpeed set type=[type],typeid=[typeid] where id=[id],這裡在更新的時候也是會用到查詢的,我的mysql版本是5.5,不能explain update,不然肯定可以驗證我所說的,這裡要更新32w+條數據,每條數據都會去更新,每條數據0.2s左右,這太嚇人了~~

解決問題

問題找到了,解決起來就容易多了~~

select的時候加了一個字段uin,改為下面這樣select uin,id,url from funkSpeed where id>=101 and id,然後更新的時候使用<code>update fuckSpeed set type=[type],typeid=[typeid] where uin=[uin] id=[id],這樣一來索引就是用上了。

三下五除二改好了程式碼,試著啟動了一個進程,看看效果如何,果然,效果提升的不是一點點,平均30+次/s,這樣大概3個小時左右就可以完成所有的更新了。

微訊號: love_skills

越努力,越幸運!越幸運,越努力!

做上CEO不是夢

贏取白富美不是夢

屌絲逆襲不是夢

就是現在! !加油
記一次MYSQL更新優化

以上就介紹了記一次MYSQL更新優化,包含了方面的內容,希望對PHP教學有興趣的朋友有幫助。

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

修復事件ID 55,50,98,140磁碟錯誤在事件檢視器 修復事件ID 55,50,98,140磁碟錯誤在事件檢視器 Mar 19, 2024 am 09:43 AM

若您在Windows11/10的事件檢視器中發現事件ID55、50、140或98,或遇到磁碟檔案系統結構損壞且無法使用的錯誤,請依照下列指南解決此問題。什麼是事件55,磁碟上的檔案系統結構損壞和不可用的意思?第55屆會議,Ntfs磁碟上的檔案系統結構損壞且無法使用。請在磁碟區上執行chkMSK實用程式當NTFS無法將資料寫入交易日誌時,會觸發事件ID55的錯誤,這將導致NTFS無法完成無法寫入交易資料的操作。這種錯誤通常發生在檔案系統損壞的情況下,可能是由於磁碟上存在壞磁區或檔案系統對磁碟子系統的不

此 Apple ID 尚未在 iTunes Store 中使用:修復 此 Apple ID 尚未在 iTunes Store 中使用:修復 Jun 10, 2024 pm 05:42 PM

使用AppleID登入iTunesStore時,可能會在螢幕上拋出此錯誤提示「此AppleID尚未在iTunesStore中使用」。沒有什麼可擔心的錯誤提示,您可以按照這些解決方案集進行修復。修正1–更改送貨地址此提示出現在iTunesStore中的主要原因是您的AppleID個人資料中沒有正確的地址。步驟1–首先,開啟iPhone上的iPhone設定。步驟2–AppleID應位於所有其他設定的頂部。所以,打開它。步驟3–在那裡,打開“付款和運輸”選項。步驟4–使用面容ID驗證您的存取權限。步驟

阿里巴巴id在哪裡看 阿里巴巴id在哪裡看 Mar 08, 2024 pm 09:49 PM

在阿里巴巴軟體中,一旦您成功註冊帳號,系統就會為您指派一個獨特的ID,這個ID將作為您在平台上的身分識別。但是對於許多用戶來說,他們會想要查詢自己的ID,但是卻不知道該如何操作。那麼本站小編帶來下文中,就將為大家帶來詳細的攻略步驟介紹,希望能幫助大家!阿里巴巴id在哪裡看答案:【阿里巴巴】-【我的】。 1.首先打開阿里巴巴軟體,進入到首頁中後我們需要點擊右下角的【我的】;2、然後來到我的頁面中後我們在頁面的上方就可以看到【id】了;阿里巴巴id跟淘寶一樣嗎阿里巴巴id和淘寶id不一樣,但二

事件 ID 4660:已刪除物件 [修復] 事件 ID 4660:已刪除物件 [修復] Jul 03, 2023 am 08:13 AM

我們的一些讀者遇到了事件ID4660。他們通常不確定該怎麼做,所以我們在本指南中解釋。刪除物件時通常會記錄事件ID4660,因此我們還將探索一些實用的方法在您的電腦上修復它。什麼是事件ID4660?事件ID4660與活動目錄中的物件相關,將由下列任一因素觸發:物件刪除–每當從ActiveDirectory中刪除物件時,都會記錄事件ID為4660的安全事件。手動變更–當使用者或管理員手動變更物件的權限時,可能會產生事件ID4660。變更權限設定、修改存取等級或新增或刪除人員或群組時,可能會發生這種情

騰訊視頻id在哪裡查看 騰訊視頻id在哪裡查看 Feb 24, 2024 pm 06:25 PM

騰訊視頻id在哪裡查看?騰訊視頻APP中是有專屬的id,但是多數的用戶不知道如何查看騰訊視頻id,接下來就是小編為用戶帶來的騰訊視頻id查看方法圖文教程,感興趣的用戶快來一起看看吧!騰訊影片使用教學騰訊影片id在哪裡查看1、先開啟騰訊影片APP,主頁右下角【個人中心】進入專區;2、之後進入到個人中心頁面,選擇【設定】功能;3、然後在設定頁面,點選最下方【退出帳號】;4、最後在下圖所示的頁面即可查看到專屬的id號。

vue取得不到id屬性怎麼辦 vue取得不到id屬性怎麼辦 Jan 29, 2023 pm 02:03 PM

vue取得不到id屬性是因為將getElementById用在了「created()」鉤子函數中,而Vue尚未完成掛載;其解決方法就是將「created() {let serachBox = document.getElementById('searchBox') ;...}」程式碼遷移到「mounted()」鉤子函數中即可。

jquery如何隱藏select元素 jquery如何隱藏select元素 Aug 15, 2023 pm 01:56 PM

jquery隱藏select元素的方法:1、hide()方法,在HTML頁面中引入jQuery庫,可以使用不同選擇器來隱藏select元素,ID選擇器將selectId替換為你實際使用的select元素的ID;2、 css()方法,使用ID選擇器選擇需要隱藏的select元素,使用css()方法將display屬性設為none,並將selectId替換為select元素的ID。

使用golang進行Select Channels Go並發式程式設計的非同步處理方法 使用golang進行Select Channels Go並發式程式設計的非同步處理方法 Sep 28, 2023 pm 05:27 PM

使用golang進行SelectChannelsGo並發式程式設計的非同步處理方法引言:並發式程式設計是現代軟體開發中的重要領域,它可以有效地提高應用程式的效能和回應能力。在Go語言中,使用Channels和Select語句可以簡單而有效率地實現並發程式設計。本文將介紹如何使用golang進行SelectChannelsGo並發式程式設計的非同步處理方法,並提供具體的

See all articles