深入浅出Mysql(四)
大批量插入數(shù)據(jù)優(yōu)化
1、對(duì)應(yīng)Myisam類型的表,可以通過(guò)以下方式快速的導(dǎo)入大量數(shù)據(jù)
這兩個(gè)命令用來(lái)打開(kāi)或者關(guān)閉Myisam表非唯一索引的更新。
2、對(duì)于InnoDB類型的表,這種方式并不能提高導(dǎo)入的效率,我們可以采取下面幾種策略:
(1)、因?yàn)镮nnoDB類型的表是按照主鍵的順序保存的,所以將導(dǎo)入的數(shù)據(jù)按照主鍵的順序排列,可以有效的提高導(dǎo)入數(shù)據(jù)的效率。如果InnoDB表沒(méi)有主鍵,那么系統(tǒng)會(huì)默認(rèn)創(chuàng)建一個(gè)內(nèi)部列作為主鍵,所以,如果可以給表創(chuàng)建一個(gè)主鍵,就可以利用這個(gè)優(yōu)勢(shì)提高導(dǎo)入數(shù)據(jù)的效率。
(2)、在導(dǎo)入數(shù)據(jù)前執(zhí)行set unique_checkes = 0,關(guān)閉唯一性校驗(yàn),在導(dǎo)入結(jié)束后執(zhí)行set unique_checks = 1,恢復(fù)唯一性校驗(yàn),可以提高導(dǎo)入的效率
(3)、如果應(yīng)用使用自動(dòng)提交的方式,建議在導(dǎo)入前執(zhí)行set autocommit = 0,導(dǎo)入結(jié)束收再執(zhí)行set autocommit = 1,也可以提高導(dǎo)入效率
優(yōu)化group by語(yǔ)句
默認(rèn)情況下,Mysql排序所有g(shù)roup by col1,col2,…的字段。查詢的方法如同在查詢中指定order by col1,col2,….。如果顯示的包括一個(gè)包含相同的列order by 子句,Mysql可以毫不減速的對(duì)他進(jìn)行優(yōu)化,盡管仍然進(jìn)行排序。
如果查詢包括group by但你還想要避免排序結(jié)果的消耗,你可以指定order by null禁止排序,例如:
優(yōu)化order by語(yǔ)句
在某些情況下,Mysql可以使用一個(gè)索引來(lái)滿足order by子句,而不需要額外的排序,where條件和order by使用相同的索引,并且order by的順序和索引順序相同,并且order by的字段都是升序或者都是降序。
例如:下列sql可以使用索引
以下情況不適用索引
select * from t1 order by key_part1 desc,key_part2 asc; -- 排序混合 select * from t1 where key2 = constant order by key1; -- 用于查詢行的關(guān)鍵字和order by中所使用的不同 select * from t1 order by key1,key2;-- 一對(duì)不同的關(guān)鍵字使用order by優(yōu)化join語(yǔ)句
假設(shè)我們要將所有沒(méi)有訂單記錄的用戶取出來(lái),可以用下面這個(gè)查詢完成:
select * from customerinfo where customer_id not in (select customer_id from salesinfo);
如果使用join來(lái)完成,速度將會(huì)快很多。尤其是salesinfo表中對(duì)customer_id建有索引的話,性能將會(huì)更好,查詢?nèi)缦?#xff1a;
join的效率更高是因?yàn)镸ysql不需要再內(nèi)存中創(chuàng)建臨時(shí)表來(lái)完成這個(gè)邏輯上需要兩步驟的查詢工作。
優(yōu)化or條件
對(duì)于or子句,如果要利用索引,則or之間的每一個(gè)條件都必須用到索引
查詢優(yōu)先還是更新(insert,update,delete)優(yōu)先
我們首先應(yīng)該確定應(yīng)用的類型,判斷應(yīng)用是以查詢?yōu)橹?#xff0c;還是以更新為主,下面我們提到的改變調(diào)度策略的方法主要指針對(duì)Myisam存儲(chǔ)引擎,對(duì)于InnoDB存儲(chǔ)引擎,語(yǔ)句的執(zhí)行時(shí)由獲得行鎖的順序決定的。
Mysql的默認(rèn)調(diào)度策略總結(jié)如下:
1、寫入操作優(yōu)先于讀取操作
2、對(duì)某張表的寫入操作某一時(shí)刻只能發(fā)生一次,寫入請(qǐng)求按照他們到來(lái)的次序來(lái)處理
3、對(duì)某張表的多個(gè)讀取操作可以同時(shí)進(jìn)行,Mysql提供了幾個(gè)語(yǔ)句調(diào)節(jié)符,允許你修改他的調(diào)度策略
(1)、low_priority關(guān)鍵字應(yīng)用于delete、insert、load data、replace和update
(2)、high_priority關(guān)鍵字應(yīng)用于select和insert語(yǔ)句
(3)、delayed關(guān)鍵字應(yīng)用于insert和replace語(yǔ)句
優(yōu)化表的數(shù)據(jù)類型
我們可以使用procedure analyse()對(duì)當(dāng)前已有用用的表類型的判斷,該函數(shù)可以對(duì)數(shù)據(jù)表中的列的數(shù)據(jù)類型提出優(yōu)化建議,可以根據(jù)應(yīng)用的實(shí)際情況酌情考慮是否實(shí)施優(yōu)化。
語(yǔ)法:
輸出的每一列信息都會(huì)對(duì)數(shù)據(jù)表中的列的數(shù)據(jù)類型提出優(yōu)化建議。第二個(gè)例子告訴procedure analyse()不要為那些包含的值多于16個(gè)或者256字節(jié)的enum類型提出建議,如果沒(méi)有這個(gè)限制,輸出信息可能很長(zhǎng),enum定義通常很難閱讀。
通過(guò)拆分,提高表的訪問(wèn)效率
這里所說(shuō)的拆分主要針對(duì)Myisam類型的表,拆分的方法分為兩種情況:
1、縱向拆分
按照應(yīng)用訪問(wèn)的頻度,將表中經(jīng)常訪問(wèn)的字段和不經(jīng)常訪問(wèn)的字段拆分成兩個(gè)表,經(jīng)常訪問(wèn)的字段盡量是定長(zhǎng)的,這樣可以有效的提高表的查詢和更新效率
2、橫向拆分
按照應(yīng)用的情況,有目的的將數(shù)據(jù)橫向拆分成幾個(gè)表或者通過(guò)分區(qū)分到多個(gè)分區(qū)中,這樣可以有效的避免Myisam表的讀取和更新導(dǎo)致鎖的問(wèn)題。
使用冗余統(tǒng)計(jì)表?使用create temporary table語(yǔ)句,他是基于session的表,表的數(shù)據(jù)保存在內(nèi)存里面,當(dāng)session斷掉后,表自然消除 對(duì)于大表的統(tǒng)計(jì)分析,如果統(tǒng)計(jì)的表數(shù)據(jù)列不大,利用insert…select 將數(shù)據(jù)遷移到臨時(shí)表比直接在大表上統(tǒng)計(jì)效率更高。
來(lái)源:http://www.voidcn.com/article/p-zgmyllre-bhe.html
總結(jié)
以上是生活随笔為你收集整理的深入浅出Mysql(四)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 厨房装修选美多语音蒸烤集成灶+美多集成水
- 下一篇: Mysql自增列,并发插入时导致死锁的问