概述
MySQL優(yōu)化分為三部分優(yōu)化:
- MySQL服務(wù)器和配置優(yōu)化
- 數(shù)據(jù)庫(kù)設(shè)計(jì)和結(jié)構(gòu)優(yōu)化
- 查詢優(yōu)化(重點(diǎn))
MySQL服務(wù)器和配置優(yōu)化
-
硬件方面
- 配置較大的內(nèi)存
- 選擇高速磁盤系統(tǒng)
- 合理分布磁盤I/O
- 選擇多處理器系統(tǒng)
- 網(wǎng)絡(luò)環(huán)境選擇
-
操作系統(tǒng)內(nèi)核
- 使用64位操作系統(tǒng)梧乘,更好地使用大內(nèi)存
- 設(shè)置noatimenodiratime
- 優(yōu)化內(nèi)核參數(shù)
- 加大文件描述符限制
- 文件系統(tǒng)選擇 xfs
-
MySQL參數(shù)配置
MySQL的配置參數(shù)都在my.ini或則my.cnf文件中。一些對(duì)性能影響較大的參數(shù)如下所示瘸羡,包括
- I/O處理的常用參數(shù);
- 最大連接數(shù)設(shè)置某饰;
- 緩存使用參數(shù)的設(shè)置检疫;
- 慢日志的參數(shù)的設(shè)置;
- InnoDB相關(guān)參數(shù)的設(shè)置等屯蹦。
key_buffer_size MySQL索引緩沖區(qū)的大小嘀趟。如果是采用MyISAM的話要重點(diǎn)設(shè)置這個(gè)參數(shù)脐区,根據(jù)(key_reads/key_read_requests)判斷 max_connections 服務(wù)器允許的最大連接數(shù),盡量不要設(shè)置太大她按,因?yàn)樵O(shè)置太大的話容易導(dǎo)致內(nèi)存溢出 wait_timeout 線程連接的超時(shí)時(shí)間牛隅,盡量不要設(shè)置很大,推薦10s thread_concurrency 線程并發(fā)利用數(shù)量酌泰,(cpu+disk)*2媒佣,根據(jù)(os中顯示的請(qǐng)求隊(duì)列和tickets)判斷 sort_buffer_size 排序緩沖區(qū)的大小胀糜。該值越大畏铆,進(jìn)行排序的速度越快 read_rnd_buffer_size 當(dāng)根據(jù)鍵進(jìn)行分類操作時(shí)獲得更快的--ORDER BY join_buffer_size join連接使用全表掃描連接的緩沖大小,根據(jù)select_full_join判斷 read_buffer_size 全表掃描時(shí)為查詢預(yù)留的緩沖大小狞甚,根據(jù)select_scan判斷 tmp_table_size 臨時(shí)內(nèi)存表的設(shè)置授霸,如果超過(guò)設(shè)置就會(huì)轉(zhuǎn)化成磁盤表巡验,根據(jù)參數(shù)(created_tmp_disk_tables)判斷 innodb_buffer_pool_size InnoDB表數(shù)據(jù)和索引的最大緩存。根據(jù)(hit riatos和FILE I/O)判斷 innodb_log_file_size(默認(rèn)5M) InnoDB引擎的redo log文件碘耳,設(shè)置較大的值意味著較長(zhǎng)的恢復(fù)時(shí)間 innodb_flush_log_at_trx_commit(默認(rèn)1) 表示何時(shí)將緩沖區(qū)數(shù)據(jù)寫入日志,并將日志文件寫入磁盤框弛。 1. 0表示每秒進(jìn)行一次log寫入cache辛辨,并flush log到磁盤; 2. 1表示在每次事務(wù)提交后執(zhí)行l(wèi)og寫入cache瑟枫,并flush log到磁盤斗搞; 3. 2表示在每次事務(wù)提交后執(zhí)行l(wèi)og寫入cache,每秒執(zhí)行一次flush log到磁盤慷妙;
數(shù)據(jù)庫(kù)設(shè)計(jì)和結(jié)構(gòu)優(yōu)化
-
數(shù)據(jù)表盡量符合范式
- [1] 1NF:表的列的具有原子性僻焚,不可再分解,即列的信息膝擂,不能分解成為更小的數(shù)據(jù)項(xiàng)虑啤;
- [2] 2NF:表中的記錄是唯一的隙弛,通常通過(guò)設(shè)計(jì)一個(gè)主鍵來(lái)實(shí)現(xiàn);
- [3] 3NF:表中不要有冗余數(shù)據(jù)狞山,也就是說(shuō)全闷,如果某個(gè)字段能夠被其它字段推導(dǎo)出來(lái),就不應(yīng)該存在萍启;
-
合理選擇存儲(chǔ)引擎
在開發(fā)中总珠,經(jīng)常使用的存儲(chǔ)引擎有MyISAM/InnoDB/Memory。
- MyISAM: 數(shù)據(jù)庫(kù)并發(fā)不大勘纯,讀多寫少局服,sql 語(yǔ)句比較簡(jiǎn)單,對(duì)事務(wù)要求不高驳遵,比如 bbs 中的發(fā)帖表腌逢,回復(fù)表;
- InnoDB:并發(fā)訪問(wèn)大超埋,寫操作比較多搏讶,有外鍵、事務(wù)等需求的應(yīng)用霍殴,系統(tǒng)內(nèi)存較大媒惕。比如訂單表,賬號(hào)表来庭;
- Memory:數(shù)據(jù)不需要入庫(kù)妒蔚,同時(shí)又頻繁的查詢和修改,速度極快月弛;
-
字段數(shù)據(jù)類型選擇
字段數(shù)據(jù)類型的選擇的一般原則:根據(jù)需求選擇合適的字段類型肴盏,在滿足需求的情況下字段類型盡可能小帽衙;只分配滿足需求的最小字符數(shù)菜皂,不要太慷慨;原因:更小的字段類型更小的字符數(shù)占用更少的內(nèi)存厉萝,占用更少的磁盤空間恍飘,占用更少的磁盤 IO 以及占用更少的帶寬。
-
CHAR 和 VARCHAR 的選取
它們的區(qū)別在于:CHAR(M) 類型的數(shù)據(jù)列里谴垫,每個(gè)值都占用 M 個(gè)字節(jié)章母,如果某個(gè)長(zhǎng)度小于 M,MySQL 就會(huì)在它的右邊用空格字符補(bǔ)足翩剪;VARCHAR(M) 類型的數(shù)據(jù)列里乳怎,每個(gè)值只占用剛好夠用的字節(jié)再加上一個(gè)用來(lái)記錄其長(zhǎng)度的字節(jié)(即總長(zhǎng)度為 L+1 字節(jié))。
二者的選取主要依據(jù)如下原則:
1.如果列數(shù)據(jù)項(xiàng)的大小一致或者相差不大前弯,則使用 CHAR蚪缀;
2.如果列數(shù)據(jù)項(xiàng)的大小差異相當(dāng)大秫逝,則使用 VARCHAR;
3.對(duì)于 MyISAM 表椿胯,盡量使用 CHAR筷登。 因?yàn)?VARCHAR 類型隨著修改容易造成磁盤碎片,使用 CHAR 的缺點(diǎn)就是占用磁盤空間哩盲;
4.對(duì)于 InnoDB 表前方,從減少空間占用量和減少磁盤 I/O 的角度,使用 VARCHAR;5.表中只要存在一個(gè) VARCHAR 類型的字段廉油,那么所有的 CHAR 字段都會(huì)自動(dòng)變成 VARCHAR 類型惠险,因此建議定長(zhǎng)和變長(zhǎng)的數(shù)據(jù)分開。
-
編碼選擇
單字節(jié):latin1
多字節(jié):utf8 (漢字占 3 個(gè)字節(jié)抒线,英文字母占用一個(gè)字節(jié))
注意:如果含有中文字符的話最好都統(tǒng)一采用 utf8 類型班巩,避免亂碼的情況發(fā)生。
-
NULL OR NOT NULL
盡可能設(shè)置每個(gè)字段為 NOT NULL嘶炭,除非有特殊的需求抱慌,原因如下:使用含有 NULL 列做索引的話會(huì)占用更多的磁盤空間,因?yàn)樗饕?NULL 列需要額外的空間來(lái)保存眨猎;進(jìn)行比較的時(shí)候抑进,程序會(huì)更復(fù)雜;含有 NULL 的列 SQL 難優(yōu)化睡陪,如果是一個(gè)組合索引寺渗,那么這個(gè) NULL 類型的字段會(huì)極大影響整個(gè)索引的效率。
-
讀寫分離
開啟 MySQL 復(fù)制兰迫,實(shí)現(xiàn)讀寫分離信殊、負(fù)載均衡(nginx、lvs)汁果,將讀的負(fù)載分?jǐn)偟蕉鄠€(gè)從服務(wù)器上涡拘,提高服務(wù)器的處理能力。
1522067459348.png?
集群和分布式理解:
集群是指多臺(tái)服務(wù)器提供同一種服務(wù)须鼎,避免單點(diǎn)失效鲸伴,可靠性高。
分布式是指將一個(gè)應(yīng)用拆分成多個(gè)服務(wù)晋控,每個(gè)服務(wù)單獨(dú)提供自己服務(wù),提高并發(fā)能力姓赤。
-
分表和分區(qū)
當(dāng)表存儲(chǔ)了百萬(wàn)級(jí)乃至千萬(wàn)級(jí)條記錄時(shí)赡译,在查詢和插入的時(shí)候耗時(shí)太長(zhǎng),性能低下不铆,如果涉及聯(lián)合查詢的情況蝌焚,性能會(huì)更加糟糕裹唆。分表和分區(qū)的目的就是減少數(shù)據(jù)庫(kù)的負(fù)擔(dān),提高數(shù)據(jù)庫(kù)的效率只洒。
分表可以分成水平拆分和垂直拆分兩種
水平拆分就是將一張大表拆分成多張小表许帐,每張小表的結(jié)構(gòu)與原表相同,只是記錄條數(shù)要少毕谴;
t_order 100萬(wàn)條數(shù)據(jù)
t_order_01 10萬(wàn)條數(shù)據(jù)成畦,0-99999
t_order_02 10萬(wàn)條數(shù)據(jù),100000-199999
...
t_order_10 10萬(wàn)條數(shù)據(jù)涝开,900000-999999
垂直拆分就是將大表中的某些字段(使用頻率低)取出來(lái)循帐,放在另一張表中。
id name sex age address 1 abc 1 25 廣東深圳 2 asd 0 22 廣東東莞 id name sex age 1 abc 1 25 2 asd 0 22 id address 1 廣東深圳 2 廣東東莞 分區(qū)是指在同一個(gè)表分區(qū)舀武,分為水平分區(qū)和垂直分區(qū)兩種拄养。
水平分區(qū)有幾種模式如下:
1.Range:定義范圍來(lái)分
2.Hash:定義Hash來(lái)分
3.Key:Hash的一種延伸
4.List(預(yù)定義列表):自己定義幾個(gè)值來(lái)分
5.Composite(復(fù)合模式):對(duì)1234組合使用
垂直分區(qū):一般將大text和BLOB列分到另一個(gè)區(qū)
1522068601203.png
查詢優(yōu)化
對(duì)查詢進(jìn)行優(yōu)化,要盡量避免全表掃描银舱,首先應(yīng)考慮在 where 及 order by 涉及的列上建立索引瘪匿。
-
應(yīng)盡量避免在 where 子句中對(duì)字段進(jìn)行 null 值判斷,否則將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描寻馏,
如:select id from t where num is null
- 最好不要給數(shù)據(jù)庫(kù)留NULL棋弥,盡可能的使用 NOT NULL填充數(shù)據(jù)庫(kù)
- 備注、描述操软、評(píng)論之類的可以設(shè)置為 NULL嘁锯,其他的最好不要使用NULL
- 不要以為 NULL 不需要空間,比如:char(100) 型聂薪,在字段建立時(shí)家乘,空間就固定了, 不管是否插入值(NULL也包含在內(nèi))藏澳,都是占用 100個(gè)字符的空間的仁锯,如果是varchar這樣的變長(zhǎng)字段, null 不占用空間
- 在num上設(shè)置默認(rèn)值0翔悠,確保表中num列沒(méi)有null值业崖,然后這樣查詢:select id from t where num = 0
-
應(yīng)盡量避免在 where 子句中使用 != 或 <> 操作符,否則將引擎放棄使用索引而進(jìn)行全表掃描蓄愁。
比如:sex要么是1要么是0双炕,當(dāng)查詢sex = 0的數(shù)據(jù)
這種寫法不用索引:select * from table where sex != 1;
這種用了索引:select * from table where sex = 0;
-
應(yīng)盡量避免在 where 子句中使用 or 來(lái)連接條件,如果一個(gè)字段有索引撮抓,一個(gè)字段沒(méi)有索引妇斤,將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描,
如:select id from t where num=10 or Name = 'admin'
可以這樣查詢:select id from t where num = 10 union all select id from t where Name = 'admin'
-
in 和 not in 也要慎用,否則會(huì)導(dǎo)致全表掃描站超,
如:select id from t where num in(1,2,3)
對(duì)于連續(xù)的數(shù)值荸恕,能用 between 就不要用 in 了:
select id from t where num between 1 and 3
很多時(shí)候用 exists 代替 in 是一個(gè)好的選擇:
select num from a where num in(select num from b)(a表數(shù)據(jù)多而b的數(shù)據(jù)少,in的效率高)
用下面的語(yǔ)句替換:
select num from a where exists(select 1 from b where num=a.num)(a表數(shù)據(jù)少而b的數(shù)據(jù)多死相,exists的效率高)
-
下面的查詢也將導(dǎo)致全表掃描(不能前置百分號(hào)):
select id from t where name like‘%abc%’若要提高效率融求,可以考慮全文檢索。
-
如果在 where 子句中使用參數(shù)算撮,也會(huì)導(dǎo)致全表掃描生宛。因?yàn)镾QL只有在運(yùn)行時(shí)才會(huì)解析局部變量,但優(yōu)化程序不能將訪問(wèn)計(jì)劃的選擇推遲到運(yùn)行時(shí)钮惠;它必須在編譯時(shí)進(jìn)行選擇茅糜。然 而,如果在編譯時(shí)建立訪問(wèn)計(jì)劃素挽,變量的值還是未知的蔑赘,因而無(wú)法作為索引選擇的輸入項(xiàng)。
如下面語(yǔ)句將進(jìn)行全表掃描:select id from t where num = @num可以改為強(qiáng)制查詢使用索引:select id from t with(index(索引名)) where num = @num
-
應(yīng)盡量避免在 where 子句中對(duì)字段進(jìn)行表達(dá)式操作预明,這將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描缩赛。
如:select id from t where num/2 = 100
應(yīng)改為:select id from t where num = 100*2
-
應(yīng)盡量避免在where子句中對(duì)字段進(jìn)行函數(shù)操作,這將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描撰糠。
如:-–name以abc開頭的id
select id from t where substring(name,1,3) = 'abc'-–‘2005-11-30’
--生成的id
select id from t where datediff(day,createdate,'2005-11-30') = 0
應(yīng)改為:select id from t where name like 'abc%'
select id from t where createdate >= '2005-11-30' and createdate < '2005-12-1'
不要在 where 子句中的“=”左邊進(jìn)行函數(shù)酥馍、算術(shù)運(yùn)算或其他表達(dá)式運(yùn)算,否則系統(tǒng)將可能無(wú)法正確使用索引阅酪。
在使用索引字段作為條件時(shí)旨袒,如果該索引是復(fù)合索引,那么必須使用到該索引中的第一個(gè)字段作為條件時(shí)才能保證系統(tǒng)使用該索引术辐,否則該索引將不會(huì)被使用砚尽,并且應(yīng)盡可能的讓字段順序與索引順序相一致。
不要寫一些沒(méi)有意義的查詢辉词,如需要生成一個(gè)空表結(jié)構(gòu):select col1,col2 into #t from t where 1=0這類代碼不會(huì)返回任何結(jié)果集必孤,但是會(huì)消耗系統(tǒng)資源的,應(yīng)改成這樣:create table #t(…)
Update 語(yǔ)句瑞躺,如果只更改1敷搪、2個(gè)字段,不要Update全部字段幢哨,否則頻繁調(diào)用會(huì)引起明顯的性能消耗赡勘,同時(shí)帶來(lái)大量日志。
對(duì)于多張大數(shù)據(jù)量(這里幾百條就算大了)的表JOIN捞镰,要先分頁(yè)再JOIN狮含,否則邏輯讀會(huì)很高顽悼,性能很差曼振。
select count(*) from table几迄;這樣不帶任何條件的count會(huì)引起全表掃描,并且沒(méi)有任何業(yè)務(wù)意義冰评,是一定要杜絕的映胁。如果要在 InnoDB下使用,建議另外弄一張統(tǒng)計(jì)表甲雅,采用 MyISAM解孙,定期做統(tǒng)計(jì)。一般的對(duì)統(tǒng)計(jì)的數(shù)據(jù)不會(huì)要求太精準(zhǔn)的情況下適用抛人。
索引并不是越多越好弛姜,索引固然可以提高相應(yīng)的 select 的效率,但同時(shí)也降低了 insert 及 update 的效率妖枚,因?yàn)?insert 或 update 時(shí)有可能會(huì)重建索引廷臼,所以怎樣建索引需要慎重考慮,視具體情況而定绝页。一個(gè)表的索引數(shù)最好不要超過(guò)6個(gè)荠商,若太多則應(yīng)考慮一些不常使用到的列上建的索引是否有 必要。
應(yīng)盡可能的避免更新 clustered 索引數(shù)據(jù)列续誉,因?yàn)?clustered 索引數(shù)據(jù)列的順序就是表記錄的物理存儲(chǔ)順序莱没,一旦該列值改變將導(dǎo)致整個(gè)表記錄的順序的調(diào)整,會(huì)耗費(fèi)相當(dāng)大的資源酷鸦。若應(yīng)用系統(tǒng)需要頻繁更新 clustered 索引數(shù)據(jù)列饰躲,那么需要考慮是否應(yīng)將該索引建為 clustered 索引。
盡量使用數(shù)字型字段臼隔,若只含數(shù)值信息的字段盡量不要設(shè)計(jì)為字符型嘹裂,這會(huì)降低查詢和連接的性能,并會(huì)增加存儲(chǔ)開銷躬翁。這是因?yàn)橐嬖谔幚聿樵兒瓦B 接時(shí)會(huì)逐個(gè)比較字符串中每一個(gè)字符焦蘑,而對(duì)于數(shù)字型而言只需要比較一次就夠了。
盡可能的使用 varchar/nvarchar 代替 char/nchar 盒发,因?yàn)槭紫茸冮L(zhǎng)字段存儲(chǔ)空間小例嘱,可以節(jié)省存儲(chǔ)空間,其次對(duì)于查詢來(lái)說(shuō)宁舰,在一個(gè)相對(duì)較小的字段內(nèi)搜索效率顯然要高些拼卵。
任何地方都不要使用 select * from t ,用具體的字段列表代替“”蛮艰,不要返回用不到的任何字段腋腮。*
盡量使用表變量來(lái)代替臨時(shí)表。如果表變量包含大量數(shù)據(jù),請(qǐng)注意索引非常有限(只有主鍵索引)即寡。
避免頻繁創(chuàng)建和刪除臨時(shí)表徊哑,以減少系統(tǒng)表資源的消耗。臨時(shí)表并不是不可使用聪富,適當(dāng)?shù)厥褂盟鼈兛梢允鼓承├谈行л撼螅纾?dāng)需要重復(fù)引用大型表或常用表中的某個(gè)數(shù)據(jù)集時(shí)墩蔓。但是梢莽,對(duì)于一次性事件, 最好使用導(dǎo)出表奸披。
在新建臨時(shí)表時(shí)昏名,如果一次性插入數(shù)據(jù)量很大,那么可以使用 select into 代替 create table阵面,避免造成大量 log 轻局,以提高速度;如果數(shù)據(jù)量不大膜钓,為了緩和系統(tǒng)表的資源嗽交,應(yīng)先create table,然后insert颂斜。
如果使用到了臨時(shí)表夫壁,在存儲(chǔ)過(guò)程的最后務(wù)必將所有的臨時(shí)表顯式刪除,先 truncate table 沃疮,然后 drop table 盒让,這樣可以避免系統(tǒng)表的較長(zhǎng)時(shí)間鎖定。
盡量避免使用游標(biāo)司蔬,因?yàn)橛螛?biāo)的效率較差邑茄,如果游標(biāo)操作的數(shù)據(jù)超過(guò)1萬(wàn)行,那么就應(yīng)該考慮改寫俊啼。
使用基于游標(biāo)的方法或臨時(shí)表方法之前肺缕,應(yīng)先尋找基于集的解決方案來(lái)解決問(wèn)題,基于集的方法通常更有效授帕。
與臨時(shí)表一樣同木,游標(biāo)并不是不可使用。對(duì)小型數(shù)據(jù)集使用 FAST_FORWARD 游標(biāo)通常要優(yōu)于其他逐行處理方法跛十,尤其是在必須引用幾個(gè)表才能獲得所需的數(shù)據(jù)時(shí)彤路。在結(jié)果集中包括“合計(jì)”的例程通常要比使用游標(biāo)執(zhí)行的速度快。如果開發(fā)時(shí) 間允許芥映,基于游標(biāo)的方法和基于集的方法都可以嘗試一下洲尊,看哪一種方法的效果更好远豺。
在所有的存儲(chǔ)過(guò)程和觸發(fā)器的開始處設(shè)置 SET NOCOUNT ON ,在結(jié)束時(shí)設(shè)置 SET NOCOUNT OFF 坞嘀。無(wú)需在執(zhí)行存儲(chǔ)過(guò)程和觸發(fā)器的每個(gè)語(yǔ)句后向客戶端發(fā)送 DONE_IN_PROC 消息躯护。
盡量避免大事務(wù)操作,提高系統(tǒng)并發(fā)能力
盡量避免向客戶端返回大數(shù)據(jù)量姆吭,若數(shù)據(jù)量過(guò)大榛做,應(yīng)該考慮相應(yīng)需求是否合理。
慢日志
show variables like 'slow_query_log';
set global slow_query_log_file = 'D:/mysql/log/slow.log';(windows無(wú)效)
set global log_queries_not_using_indexes = on;
set global long_query_time = 1;
set global slow_query_log=on;
執(zhí)行sql的主機(jī)信息:# User@Host: root[root] @ localhost [::1] Id: 3
sql執(zhí)行信息:# Query_time: 0.012032 Lock_time: 0.011532 Rows_sent: 2 Rows_examined: 2
sql執(zhí)行時(shí)間:SET timestamp=1511101457;
sql執(zhí)行內(nèi)容:select * from store limit 10;
案例
實(shí)際案例分析拆分大的 DELETE 或INSERT 語(yǔ)句内狸,批量提交SQL語(yǔ)句。
如果你需要在一個(gè)在線的網(wǎng)站上去執(zhí)行一個(gè)大的 DELETE 或 INSERT 查詢厘擂,你需要非常小心昆淡,要避免你的操作讓你的整個(gè)網(wǎng)站停止相應(yīng)。因?yàn)檫@兩個(gè)操作是會(huì)鎖表的刽严,表一鎖住了昂灵,別的操作都進(jìn)不來(lái)了。
Apache 會(huì)有很多的子進(jìn)程或線程舞萄。所以眨补,其工作起來(lái)相當(dāng)有效率,而我們的服務(wù)器也不希望有太多的子進(jìn)程倒脓,線程和數(shù)據(jù)庫(kù)鏈接撑螺,這是極大的占服務(wù)器資源的事情,尤其是內(nèi)存崎弃。
如果你把你的表鎖上一段時(shí)間甘晤,比如30秒鐘,那么對(duì)于一個(gè)有很高訪問(wèn)量的站點(diǎn)來(lái)說(shuō)饲做,這30秒所積累的訪問(wèn)進(jìn)程/線程线婚,數(shù)據(jù)庫(kù)鏈接,打開的文件數(shù)盆均,可能不僅僅會(huì)讓你的WEB服務(wù)崩潰塞弊,還可能會(huì)讓你的整臺(tái)服務(wù)器馬上掛了。
所以泪姨,如果你有一個(gè)大的處理游沿,你一定把其拆分,使用 LIMIT oracle(rownum),sqlserver(top)條件是一個(gè)好的方法驴娃。下面是一個(gè)mysql示例:
while(1){
//每次只做1000條
mysql_query(“delete from logs where log_date <= ’2012-11-01’ limit 1000”);
if(mysql_affected_rows() == 0){
//刪除完成奏候,退出!
break唇敞;
}
//每次暫停一段時(shí)間蔗草,釋放表讓其他進(jìn)程/線程訪問(wèn)咒彤。
usleep(50000)
}