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