mysql更新效率優化 MYSQL更新優化實錄

2021-10-17 11:55:50 字數 3308 閱讀 9437

引言

今天(august 5, 2015 5:34 pm)在給資料庫中一張表的結構做一次調整,新增了幾個字段,後面對之前的資料進行重新整理,重新整理的內容是:對其中的乙個已有欄位url進行匹配,然後更新新加的字段type和typeid。後來就寫了個shell指令碼來刷資料,結果執行shell指令碼後我就懵了,怎麼這麼慢~~~

情景再現

create table `****speed` (

`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;

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

首先根據乙個id範圍獲取到一定數量的資料

select id,url from funkspeed where id>=101 and id<=200;

遍歷所有的資料,對每一條資料進行更新

#首先對資料進行處理,匹配獲取type和typeid

update ****speed set type=[type],typeid=[typeid] where id=[id]

按照上面的思路搞了之後,發現更新特別的慢,平均每秒鐘3~5個左右,我也是醉了,我看看要更新的資料,總共有32w+條,這樣更新下來大概需要24h+,也就是1天還要多,額~~哭了,想想肯定是**出問題了。

發現問題

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

./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 &

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

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

mysql> select id,url from funkspeed where id>=0 and id<=200;

empty set (0.18 sec)

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

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)

然後使用聯合索引:

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)

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

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

問題發生在update ****speed 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<=200;,然後更新的時候使用update ****speed set type=[type],typeid=[typeid] where uin=[uin] id=[id],這樣一來索引就是用上了。

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

總結mysql語句級優化:

1.   效能查的讀語句,在innodb中統計行數,建議另外弄一張統計表,採用myisam,定期做統計.一般的對統計的資料不會要求太精準的情況下適用。

2.   盡量不要在資料庫中做運算。

3.   避免負向查詢和%字首模糊查詢。

4.   不在索引列做運算或者使用函式。

5.   不要在生產環境程式中使用select * from 的形式查詢資料。只查詢需要使用的列。

6.   查詢盡可能使用limit減少返回的行數,減少資料傳輸時間和頻寬浪費。

7.   where子句盡可能對查詢列使用函式,因為對查詢列使用函式用不到索引。

8.   避免隱式型別轉換,例如字元型一定要用'',數字型一定不要使用''。

10. 聯表查詢的時候,記得把小結果集放在前面,遵循小結果集驅動大結果集的原則。

11. 開啟慢查詢,定期用explain優化慢查詢中的sql語句。

mysq基礎優化

skip name resolve skip locking skip innodb skip bdb key buffer 1g記憶體推薦設定為256m,2g記憶體推薦設定為512m wait timeout 3或者5 2g記憶體推薦設定為5 max connections 如果訪問量很大可以設定...

Mysql更新效能優化 MySQL效能優化

效能優化是通過某些有效的方法來提高mysql的執行速度,減少占用的磁碟空間。效能優化包含很多方面,例如優化查詢速度,優化更新速度和優化mysql伺服器等。本文介紹方法的主要有 優化查詢 優化資料庫結構 優化mysql伺服器 資料庫管理人員可以使用show status語句來查詢mysql資料庫的效能...

MySQL優化之COUNT 效率

說到mysql的count 的效率,發現越說越說不清楚,乾脆寫下來,分享給大家。count 與count col 網上搜尋了下,發現各種說法都有 比如認為count col 比count 快的 認為count 比count col 快的 還有朋友很搞笑的說到這個其實是看人品的。在不加where限制條...