目錄
前言
一、一些緣由
1、性能分析
二、插入方式調(diào)整
1、批量插入的實(shí)現(xiàn)
2、MP的批量插入實(shí)現(xiàn)
3、日志的配置
三、默認(rèn)處理方式
1、基礎(chǔ)程序代碼
2、執(zhí)行情況
四、提升調(diào)試日志等級(jí)
1、在logback中進(jìn)行設(shè)置
2、提升后的效果
五、總結(jié)
前言
????????在現(xiàn)代軟件開(kāi)發(fā)中,性能優(yōu)化是一個(gè)永恒的話題,尤其是在處理大規(guī)模數(shù)據(jù)時(shí),如何提升數(shù)據(jù)庫(kù)操作的效率成為了一個(gè)關(guān)鍵問(wèn)題。在數(shù)據(jù)庫(kù)操作中,批量插入空間矢量數(shù)據(jù)是一個(gè)常見(jiàn)的需求,尤其是在地理信息系統(tǒng)(GIS)和空間數(shù)據(jù)分析領(lǐng)域。調(diào)試日志是軟件開(kāi)發(fā)中不可或缺的工具,它幫助開(kāi)發(fā)者追蹤程序的運(yùn)行狀態(tài),定位問(wèn)題和異常。然而,日志記錄本身是一個(gè)資源密集型的操作,尤其是在生產(chǎn)環(huán)境中,過(guò)多的日志記錄可能會(huì)對(duì)性能產(chǎn)生負(fù)面影響。對(duì)于空間矢量數(shù)據(jù)的批量插入操作,這種影響尤為明顯,因?yàn)檫@類操作通常涉及大量的I/O操作和數(shù)據(jù)庫(kù)交互。
????????盡管調(diào)試日志對(duì)于開(kāi)發(fā)和問(wèn)題排查至關(guān)重要,但在生產(chǎn)環(huán)境中,它們可能會(huì)成為性能瓶頸。每次日志記錄都會(huì)涉及到I/O操作,這會(huì)占用CPU時(shí)間和磁盤I/O資源。在批量插入空間矢量數(shù)據(jù)時(shí),如果日志記錄過(guò)于頻繁,可能會(huì)導(dǎo)致以下問(wèn)題:
- 降低I/O效率:日志記錄會(huì)占用磁盤I/O資源,這可能會(huì)與數(shù)據(jù)庫(kù)操作競(jìng)爭(zhēng)資源,導(dǎo)致整體性能下降。
- 增加延遲:日志記錄可能會(huì)引入額外的延遲,尤其是在高并發(fā)情況下,這會(huì)直接影響到批量插入操作的響應(yīng)時(shí)間。
- 資源競(jìng)爭(zhēng):日志記錄和數(shù)據(jù)庫(kù)操作可能會(huì)競(jìng)爭(zhēng)有限的系統(tǒng)資源,如CPU和內(nèi)存,這可能會(huì)導(dǎo)致性能瓶頸。
????????調(diào)試日志是一把雙刃劍,它在幫助開(kāi)發(fā)者解決問(wèn)題的同時(shí),也可能對(duì)生產(chǎn)環(huán)境的性能產(chǎn)生影響。在處理空間矢量數(shù)據(jù)的批量插入時(shí),合理控制和優(yōu)化日志記錄是提升性能的關(guān)鍵。本文通過(guò)在MybatisPlus中調(diào)整插入SQL的輸出對(duì)比前后的耗時(shí)與內(nèi)存的占用,最大限度地減少對(duì)性能的負(fù)面影響。本文將深入探討這些策略的具體實(shí)現(xiàn)和最佳實(shí)踐,以期為Java開(kāi)發(fā)者提供實(shí)用的指導(dǎo)和建議。
一、一些緣由
????????其實(shí)在日常工作當(dāng)中,空間矢量數(shù)據(jù)的數(shù)據(jù)量都是非常大。不僅是范圍大,屬性數(shù)據(jù)也尤其多,不僅屬性列多,而且數(shù)據(jù)行數(shù)也可能非常多。那么我們?cè)谑褂肙RM框架在操作這些數(shù)據(jù)的時(shí)候,在進(jìn)行空間數(shù)據(jù)入庫(kù)的時(shí)候尤其需要注意性能的影響。有一些程序需要追求高性能,尤其是一些需要快速計(jì)算的場(chǎng)景,用戶需要盡快的將數(shù)據(jù)入庫(kù),好開(kāi)展后續(xù)的業(yè)務(wù)。
????????之前有一個(gè)朋友給發(fā)了私信,說(shuō)他們?cè)谔幚砭€上的生產(chǎn)數(shù)據(jù)時(shí),數(shù)據(jù)的規(guī)模大約是幾十W的規(guī)模。在使用GeoTools讀取Shapefile后,然后調(diào)用Mybatis-Plus來(lái)進(jìn)行數(shù)據(jù)入庫(kù)。它的整體性能不高,耗時(shí)比較久,然后就找到博主聊了一下。原始聊天截圖就不放出來(lái)了。分享其中遇到的一些問(wèn)題:
????????1、這位朋友在進(jìn)行批量數(shù)據(jù)入庫(kù)的時(shí)候,使用循環(huán)來(lái)進(jìn)行調(diào)用,沒(méi)有使用批量操作。
????????2、系統(tǒng)的日志級(jí)別開(kāi)的比較低,為了方便監(jiān)控程序,系統(tǒng)的日志級(jí)別在生產(chǎn)環(huán)境上也是Debug。
????????3、服務(wù)器在空間數(shù)據(jù)庫(kù)入庫(kù)時(shí),內(nèi)存占用較高。
1、性能分析
????????在了解了一些程序的執(zhí)行細(xì)節(jié)之后,我也做了一個(gè)對(duì)照實(shí)驗(yàn)。實(shí)驗(yàn)的主要目的是對(duì)比應(yīng)用程序中調(diào)試日志的輸出對(duì)性能影響 ,主要方法就是在程序執(zhí)行時(shí)打開(kāi)和關(guān)閉系統(tǒng)日志,通過(guò)觀察打開(kāi)前后的應(yīng)用程序執(zhí)行消耗時(shí)間和使用Java VisualVM監(jiān)控的CPU和內(nèi)存消耗情況來(lái)對(duì)比。
二、插入方式調(diào)整
????????為了首先將應(yīng)用程序的插入調(diào)整到一個(gè)比較好的執(zhí)行狀態(tài),我們先把原來(lái)的循環(huán)插入的方式進(jìn)行了修改,改成批量插入的形式。因此這里有必要對(duì)批量插入的具體實(shí)現(xiàn)進(jìn)行一個(gè)簡(jiǎn)單的介紹。
1、批量插入的實(shí)現(xiàn)
????????在我們的代碼中,使用的ORM框架是Mybatis-Plus,熟悉這個(gè)框架的小伙伴們一定知道。在MP中除了有單個(gè)插入的方法,還提供了一個(gè)批量插入的實(shí)現(xiàn)。因此,如果您是使用了MP這種的增強(qiáng)框架,那么改造起來(lái)還是比較快的,否則就需要大家自己去實(shí)現(xiàn)批量插入的方法。在MP中需要調(diào)用service提供的saveBatch(List,Size)即可。在在我的示例代碼中,實(shí)現(xiàn)批量插入的關(guān)鍵代碼如下所示:
2、MP的批量插入實(shí)現(xiàn)
????????上一節(jié)中對(duì)Mp的批量插入的方法進(jìn)行了調(diào)用,這里我們依然對(duì)saveBatch方法進(jìn)行簡(jiǎn)單的介紹,好讓大家對(duì)saveBatch有一個(gè)直觀的印象。我們可以打開(kāi)ServiceImpl的實(shí)現(xiàn)類中的以下代碼:
????????這里的方法表示首先獲取sql的Statement對(duì)象,然后調(diào)用批量執(zhí)行的方法。被調(diào)用的方法如下:
????????來(lái)看一下insert方法的處理邏輯,最終的執(zhí)行update的方法如下:
????????當(dāng)然大家在使用這個(gè)類的時(shí)候還是非常方便的,只要調(diào)用相應(yīng)的方法即可實(shí)現(xiàn)分批導(dǎo)入。
3、日志的配置
????????在實(shí)例的應(yīng)用開(kāi)發(fā)過(guò)程中,日志的輸出與管理,我們使用Logback組件。在最開(kāi)始的時(shí)候,在對(duì)比實(shí)驗(yàn)中,首先我們采用默認(rèn)的方式,即對(duì)應(yīng)的ORM處理組件中的日志級(jí)別使用默認(rèn)方法。具體如何在Logback中進(jìn)行日志的設(shè)置,請(qǐng)大家結(jié)合互聯(lián)網(wǎng)相關(guān)資料進(jìn)行查詢,這些都是比較成熟的。
三、默認(rèn)處理方式
????????對(duì)比實(shí)驗(yàn)的第一種實(shí)現(xiàn)方法就是采用默認(rèn)的方法,即使用默認(rèn)的日志級(jí)別。但是在最開(kāi)始時(shí),我們還是給出測(cè)試的代碼的全部。如果您也感興趣,可以替換相應(yīng)的文件來(lái)進(jìn)行驗(yàn)證這個(gè)過(guò)程。測(cè)試結(jié)果可能隨著數(shù)據(jù)量的不同,數(shù)據(jù)屬性字段的不同而有所不同。
1、基礎(chǔ)程序代碼
????????為了還原網(wǎng)友提出的問(wèn)題,也能盡快的找到原因。我們這里就以之前的全球主要城市為例,重點(diǎn)講解如何進(jìn)行數(shù)據(jù)的處理和融合,以及最終如何進(jìn)入到數(shù)據(jù)庫(kù)中。實(shí)例代碼如下:
????????在不關(guān)閉執(zhí)行SQL日志的情況,我們來(lái)看一下它的相關(guān)性能指標(biāo)。
2、執(zhí)行情況
????????在默認(rèn)情況下,這段程序在執(zhí)行過(guò)程中會(huì)輸出大量的調(diào)試日志,如下圖所示:
????????在我們的控制臺(tái)中有許多的插入日志,同時(shí)可以看到,整個(gè)空間數(shù)據(jù)入庫(kù)的時(shí)間為29512毫秒,即將近30秒。除了時(shí)間的消耗,我們?cè)賮?lái)看一內(nèi)存方面的消耗。
????????可以很直觀的看到,在進(jìn)行大量的日志輸出時(shí),內(nèi)存的使用量還是比較大,同時(shí)根據(jù)不同的批次呈現(xiàn)一個(gè)比較有規(guī)律的上升和下降,而最大的內(nèi)存使用接近1000MB左右。 接下來(lái),我們?cè)賮?lái)看一下關(guān)閉日志輸出后的效果。
四、提升調(diào)試日志等級(jí)
????????為了實(shí)現(xiàn)在運(yùn)行時(shí)將這個(gè)插入SQL的日式調(diào)試等級(jí),我們?cè)贚ogback中進(jìn)行相應(yīng)的配置。以此來(lái)驗(yàn)證在提升SQL調(diào)試日志的等級(jí)后,這個(gè)批量插入的方法是不是有一個(gè)性能的提升。
1、在logback中進(jìn)行設(shè)置
????????在系統(tǒng)中,我們采用logback來(lái)進(jìn)行日志的配置,因此我們首先需要在logback中進(jìn)行相應(yīng)的設(shè)置。將日志的級(jí)別從debug提升到error,只有在發(fā)生錯(cuò)誤的時(shí)候才進(jìn)行輸出。設(shè)置的關(guān)鍵代碼如下所示:
請(qǐng)注意,這里的com.yelang.project.extend.earthquake.mapper.Ne10mPopulatedPlacesMapper標(biāo)識(shí)我們需要關(guān)閉的ORM類的全名。我們將他的日志級(jí)別提升到了error。
2、提升后的效果
????????在將輸出日志關(guān)閉之后,在控制臺(tái)中首先就沒(méi)有了sql的調(diào)試日志,說(shuō)明配置成功。
????????可以看到控制臺(tái)很干凈,調(diào)試的SQL日志已經(jīng)被清理掉。同時(shí)注意耗時(shí)情況,變成了7046,也就是7秒的時(shí)間就完成了處理。在來(lái)后臺(tái)看一下是不是真的處理成功。在數(shù)據(jù)庫(kù)進(jìn)行相應(yīng)的數(shù)據(jù)查詢。
????????可以看到,數(shù)據(jù)的總條數(shù)也是7342條。因此可以判斷,關(guān)閉sql調(diào)試日志后,對(duì)時(shí)間的消耗降低了很多,從30秒優(yōu)化到了7秒,?大概提升76%;再來(lái)看一下內(nèi)存的占用情況。
????????相對(duì)于默認(rèn)的處理情況而言,提升了日志等級(jí)的處理方式,其內(nèi)存占用更加平穩(wěn),波動(dòng)小。同時(shí)最大的內(nèi)存占用在700MB左右,更多是500MB以下。從側(cè)面也說(shuō)明了優(yōu)化的效果。
五、總結(jié)
?????????以上就是本文的主要內(nèi)容,本文通過(guò)在MybatisPlus中調(diào)整插入SQL的輸出對(duì)比前后的耗時(shí)與內(nèi)存的占用,最大限度地減少對(duì)性能的負(fù)面影響。文章通過(guò)對(duì)照實(shí)驗(yàn),對(duì)比了開(kāi)啟調(diào)試日志和關(guān)閉調(diào)試日志后的數(shù)據(jù)插入性能,從對(duì)比實(shí)驗(yàn)結(jié)果可以看到。關(guān)閉調(diào)試日志后,我們的應(yīng)用程序耗時(shí)更短,同時(shí)內(nèi)存的占用也更低。如果在生產(chǎn)環(huán)境中進(jìn)行使用,尤其是新手同志,為了觀察參數(shù)就留下了很多調(diào)試信息,這樣反而加大了系統(tǒng)的負(fù)擔(dān)。所以要請(qǐng)大家一定綜合理性的評(píng)估,關(guān)閉不必要的調(diào)試日志,讓應(yīng)用程序的性能最大。行文倉(cāng)庫(kù),定有許多不足之處,如有不足,在此懇請(qǐng)各位專家在評(píng)論區(qū)批評(píng)指出,不勝感激。