dat文本导入mysql_mysql学习笔记(九) 增删改查的优化
生活随笔
收集整理的這篇文章主要介紹了
dat文本导入mysql_mysql学习笔记(九) 增删改查的优化
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
一、大批量插入數(shù)據(jù)當(dāng)使用load命令導(dǎo)入數(shù)據(jù)的時(shí)候,可以適當(dāng)?shù)奶岣邔?dǎo)入的速度。對(duì)于myisam存儲(chǔ)引擎的表可以通過(guò)下述方法快速的導(dǎo)入大量的數(shù)據(jù)。Alter table tablename disable keys;Loading dateAlter table tabename enable keys;其中disable keys和enable keys用來(lái)打開(kāi)或者關(guān)閉myisam表非唯一索引的更新。在導(dǎo)入大量的數(shù)據(jù)到一個(gè)非空的myisam表的時(shí)候,通過(guò)設(shè)置這兩個(gè)命令可以提高導(dǎo)入的效率。對(duì)于當(dāng)如大量的數(shù)據(jù)到一個(gè)空的myisam表,默認(rèn)就是先導(dǎo)入數(shù)據(jù)然后才創(chuàng)建索引的,所以不用進(jìn)行設(shè)置。通過(guò)對(duì)比發(fā)現(xiàn)其有六倍的速率變化。Load data infile ‘/home/data/file.sql’ into table film;Alter table file disable keys;Load data infile ‘/home/data/file.sql’ into table film;Alter table file enable keys;上邊是對(duì)myisam表進(jìn)行數(shù)據(jù)導(dǎo)入時(shí)的優(yōu)化方法,對(duì)于innodb類型的表,這種方式不能提高導(dǎo)入數(shù)據(jù)的效率,但是可以通過(guò)下面幾種方式提高innodb表的導(dǎo)入效率。(1)因?yàn)閕nnodb類型的表是按照主鍵的順序保存的,所以將要導(dǎo)入的表的數(shù)據(jù)按照主鍵的順序排列,可以有效的提高導(dǎo)入數(shù)據(jù)的效率。類如text3.sql是按照表的主鍵順序存儲(chǔ)的,那么導(dǎo)入共耗時(shí)27.8秒。而沒(méi)有任何順序的文本存儲(chǔ)居然要耗時(shí)31.16秒。(2)在導(dǎo)入數(shù)據(jù)前執(zhí)行set unique_check=0,關(guān)閉唯一性校驗(yàn),在導(dǎo)入結(jié)束后執(zhí)行set unique=1,恢復(fù)唯一性校驗(yàn),可以提高導(dǎo)入的效率。(3)如果應(yīng)用使用自動(dòng)提交的方式,建議在導(dǎo)入前執(zhí)行set autocommit=0,關(guān)閉自動(dòng)提交,導(dǎo)入結(jié)束之后再執(zhí)行set autocommit=1,打開(kāi)自動(dòng)提交,這樣也可以提高導(dǎo)入的效率。二、優(yōu)化insert語(yǔ)句當(dāng)進(jìn)行數(shù)據(jù)的insert的時(shí)候,可以考慮采用以下幾種優(yōu)化方式。如果同時(shí)從同一客戶插入很多行,應(yīng)該盡量使用多個(gè)值表的insert語(yǔ)句。這種方式將大大縮減客戶端與數(shù)據(jù)庫(kù)之間的關(guān)聯(lián),關(guān)閉等的消耗。使得效率比分開(kāi)執(zhí)行單個(gè)insert語(yǔ)句要快。Insert into test value(1,2),(2,3),(3,4),....如果從不同的客戶端插入很多行,可以通過(guò)insert delayed語(yǔ)句得到更高的速度,delayed的含義是讓insert語(yǔ)句馬上執(zhí)行,其實(shí)數(shù)據(jù)被放到內(nèi)存的隊(duì)列中,并沒(méi)有真正的寫入磁盤,這比每條語(yǔ)句分別插入要快的多;low priority剛好相反,在所有用戶對(duì)表的讀寫完成之后才進(jìn)行插入。將索引文件和數(shù)據(jù)文件分在不同的磁盤上存儲(chǔ)如果進(jìn)行批量插入,可以通過(guò)bulk_insert_buffer_size變量值的方法來(lái)提高速度,但是這只能對(duì)myisam表使用。當(dāng)從一個(gè)文本文件裝載到一個(gè)表時(shí),使用load data infile。這通常比使用很多insert語(yǔ)句快20倍。三、優(yōu)化order by語(yǔ)句大家都知道order by在某些情況下order by是不支持排序的,但是如果將待排序的字段設(shè)置成為索引,而且該索引還有順序,那么就可以在排序的時(shí)候快速一些。在mysql中將不能直接通過(guò)索引排序,而是要通過(guò)返回值進(jìn)行排序操作的排序叫做filesort排序,filesort并不代表通過(guò)磁盤文件進(jìn)行排序,而只是說(shuō)進(jìn)行了排序操作,至于排序操作是否使用磁盤文件或者零時(shí)表等,擇取決于mysql服務(wù)器對(duì)排序參數(shù)的設(shè)置和需要排序的數(shù)據(jù)大小。例如,按照商店store_id排序返回所有客戶記錄時(shí),出現(xiàn)了對(duì)全表掃描的結(jié)果排序。Filesort是通過(guò)相應(yīng)的排序算法,將取得的數(shù)據(jù)在sort_buffer_size系統(tǒng)變量設(shè)置的內(nèi)存排序區(qū)中進(jìn)行排序,如果內(nèi)存裝載不下,他就會(huì)將磁盤上的數(shù)據(jù)進(jìn)行分片。再對(duì)各個(gè)數(shù)據(jù)塊進(jìn)行排序,如果內(nèi)存裝載不下,它將在磁盤上的數(shù)據(jù)進(jìn)行分塊,再對(duì)各個(gè)數(shù)據(jù)塊進(jìn)行排序,然后將各個(gè)塊合并成有序的結(jié)果集。Sort_buffer_size設(shè)置的排序區(qū)是每個(gè)線程獨(dú)有的,所以同一時(shí)刻mysql中會(huì)存在多個(gè)sort buffer排序區(qū)。在我們了解了mysql排序方式下,優(yōu)化的目標(biāo)就清晰了,盡量減少額外的排序,通過(guò)索引直接返回有序數(shù)據(jù),where條件和order by使用相同的索引,并且order by的順序和索引順序相同,并且order by的字段都是升序或者都是降序。否則肯定會(huì)有額外的排序操作,就會(huì)出現(xiàn)filesort。Filesort的優(yōu)化通過(guò)創(chuàng)建合適的索引能夠減少filesort的出現(xiàn),但是在某些情況下,條件限制不能出現(xiàn)讓filesort消失,那就需要想辦法加快filesort的操作,對(duì)于filesort來(lái)說(shuō),mysql有兩種排序算法。分別為兩次掃描算法和一次掃描算法。兩次掃描首先通過(guò)條件取出排序字段和行指針信息,然后在sort buffer中排序,如果sort buffer不夠,則在臨時(shí)表temporary table中存儲(chǔ)排序結(jié)果,完成排序之后根據(jù)行指針回表讀取記錄。因?yàn)樾枰L問(wèn)兩次數(shù)據(jù),第一次獲取排序字段和行指針信息,第二次根據(jù)行指針獲取記錄,尤其是第二次讀取操作可能導(dǎo)致大量的io操作,優(yōu)點(diǎn)是排序的時(shí)候內(nèi)存開(kāi)銷較小。一次掃描是一次性取出滿足條件的行的所有字段,然后在排序區(qū)sort buffer中排序后直接輸出結(jié)果集,排序的時(shí)候內(nèi)存開(kāi)銷比較大,但是排序的效率要比兩次掃描高。Mysql通過(guò)比較系統(tǒng)變量max_length_for_sort_data的大小和Query語(yǔ)句取出字段總大小判斷使用哪種排序算法,如果max_length_for_sort_data更大,那么使用第二種優(yōu)化之后的算法,否則采用第一種。所以適當(dāng)?shù)男薷膍ax_length_for_data的值能夠讓mysql選擇更優(yōu)化的filesort排序算法。當(dāng)然,假如max_length_for_data設(shè)置的過(guò)大,會(huì)造成mysql利用率過(guò)低和磁盤IO過(guò)高,所以平衡很重要。適當(dāng)?shù)募哟髎ort_buffer_size排序區(qū),盡量讓排序在內(nèi)存中完成,而不是通過(guò)創(chuàng)建零時(shí)表放到文件中進(jìn)行,當(dāng)然也不能無(wú)限加到sort_buffer_size排序區(qū),因?yàn)閟ort_buffer_size參數(shù)是每個(gè)線程獨(dú)占的,設(shè)置的過(guò)高。也會(huì)導(dǎo)致服務(wù)器swap嚴(yán)重,要考慮數(shù)據(jù)庫(kù)活動(dòng)連接數(shù)和服務(wù)器內(nèi)存的大小來(lái)適當(dāng)?shù)脑O(shè)置。盡量使用必要的字段,select具體的字段名稱,而不是select * 選擇所有字段,這樣可以減少排序區(qū)域的使用。提高sql的性能。
總結(jié)
以上是生活随笔為你收集整理的dat文本导入mysql_mysql学习笔记(九) 增删改查的优化的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 12306 抢票项目霸榜 GitHub,
- 下一篇: django简介及环境搭建