新聞中心
提升sqlite數(shù)據(jù)庫執(zhí)行效率的方法探究

創(chuàng)新互聯(lián)主要從事網(wǎng)站設(shè)計(jì)制作、成都做網(wǎng)站、網(wǎng)頁設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)西山,10余年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):13518219792
SQLite作為一款輕量級(jí)、快速、可靠的關(guān)系型數(shù)據(jù)庫管理系統(tǒng),被廣泛運(yùn)用于移動(dòng)設(shè)備和嵌入式設(shè)備中。但是,在實(shí)際的開發(fā)過程中,由于數(shù)據(jù)規(guī)模和復(fù)雜性的增加,SQLite數(shù)據(jù)庫的執(zhí)行效率可能會(huì)逐漸降低。為了解決這個(gè)問題,本文將探究提升SQLite數(shù)據(jù)庫執(zhí)行效率的方法。
一、優(yōu)化數(shù)據(jù)結(jié)構(gòu)
SQLite是使用文件系統(tǒng)作為儲(chǔ)存結(jié)構(gòu)進(jìn)行存儲(chǔ)的,因此在數(shù)據(jù)量較大的情況下,儲(chǔ)存結(jié)構(gòu)的優(yōu)化將直接影響數(shù)據(jù)庫的性能。一種比較有效的優(yōu)化方式是使用索引。索引可以提高查詢效率,并且可以確保信息的無重復(fù)性。但是過多的索引同樣會(huì)影響性能,因此需要根據(jù)實(shí)際需求進(jìn)行合理的索引設(shè)計(jì)。此外,還可以使用預(yù)編譯SQL、B-tree等數(shù)據(jù)結(jié)構(gòu)來優(yōu)化查詢效率。
二、避免冗余查詢
在數(shù)據(jù)庫設(shè)計(jì)中,經(jīng)常會(huì)出現(xiàn)多個(gè)查詢語句中出現(xiàn)相同的數(shù)據(jù)。為了避免反復(fù)查詢同一個(gè)數(shù)據(jù),可以使用緩存技術(shù)來提高查詢效率。在每次查詢時(shí)先判斷緩存中是否已存在該數(shù)據(jù),如果已存在則直接從緩存中讀取,避免反復(fù)查詢。
三、合理使用事務(wù)
事務(wù)可以將多個(gè)SQL語句一起執(zhí)行,避免了多次的IO操作,從而提高了性能。但是,在使用事務(wù)時(shí)需要考慮具體情況,盡可能減少事務(wù)的使用頻率,以免程序邏輯復(fù)雜度增加,影響數(shù)據(jù)庫的性能。
四、優(yōu)化IO操作
在SQLite數(shù)據(jù)庫操作中,最耗費(fèi)時(shí)間和資源的操作之一就是I/O操作。因此,要想提高SQLite數(shù)據(jù)庫的執(zhí)行效率,就必須優(yōu)化I/O操作。目前,常用的優(yōu)化方式包括:
1. 合理設(shè)置PRAGMA,提高緩存的利用率和減少寫操作的次數(shù);
2. 為數(shù)據(jù)庫文件分配較大的緩存區(qū),以減少讀寫操作對(duì)磁盤的頻繁訪問;
3. 定期清空緩存以減少對(duì)磁盤的頻繁訪問。
五、使用多線程技術(shù)
SQLite允許多個(gè)并發(fā)讀操作,但不支持并發(fā)寫操作。因此,在多線程環(huán)境下使用SQLite數(shù)據(jù)庫,可以同時(shí)進(jìn)行多個(gè)讀操作,從而提高查詢效率。但是,多線程操作需要注意線程同步問題,避免出現(xiàn)數(shù)據(jù)混亂的情況。
六、減少數(shù)據(jù)轉(zhuǎn)換和拷貝
在SQLite數(shù)據(jù)庫中,經(jīng)常需要將數(shù)據(jù)從內(nèi)存中讀取,或者將數(shù)據(jù)從內(nèi)存中寫入數(shù)據(jù)庫。在這個(gè)過程中,數(shù)據(jù)需要進(jìn)行轉(zhuǎn)換和拷貝,從而影響了程序的執(zhí)行效率。為了減少這種影響,可以通過使用結(jié)構(gòu)體和指針等方式,直接訪問內(nèi)存中的數(shù)據(jù),從而避免頻繁的數(shù)據(jù)轉(zhuǎn)換和拷貝。
綜上所述,SQLite數(shù)據(jù)庫的執(zhí)行效率取決于多種因素,包括數(shù)據(jù)結(jié)構(gòu)的優(yōu)化、避免冗余查詢、合理使用事務(wù)、優(yōu)化IO操作、使用多線程技術(shù)、減少數(shù)據(jù)轉(zhuǎn)換和拷貝等。開發(fā)人員在實(shí)際應(yīng)用中可以根據(jù)具體的應(yīng)用場(chǎng)景,選擇合適的方法來提升SQLite數(shù)據(jù)庫的執(zhí)行效率,從而確保數(shù)據(jù)庫的性能和穩(wěn)定性。
成都網(wǎng)站建設(shè)公司-創(chuàng)新互聯(lián)為您提供網(wǎng)站建設(shè)、網(wǎng)站制作、網(wǎng)頁設(shè)計(jì)及定制高端網(wǎng)站建設(shè)服務(wù)!
sqlitememory原理
SQLite創(chuàng)建的數(shù)據(jù)庫有一種模式IN-MEMORY,但是它并不表示SQLite就成了一個(gè)內(nèi)存數(shù)據(jù)庫。IN-MEMORY模式可以簡單地理解為,(2023 表述勘誤:本來創(chuàng)建的數(shù)據(jù)庫文件是基于磁盤的,現(xiàn)在整個(gè)文件使用內(nèi)存空間來代替磁盤空間,沒有了文件作為backingstore,不必在修改數(shù)據(jù)庫后將緩存頁提交到文件系統(tǒng)),其它操作保持一致。也就是數(shù)據(jù)庫的設(shè)計(jì)沒有根本改變。
inmemory與tempdb是兩種節(jié)約模式,節(jié)約的對(duì)象為(rollback)日志文件以及數(shù)據(jù)庫文件,減少IO。inmemory將日志寫在內(nèi)存,并且去除數(shù)據(jù)庫文件作為backingStore,緩存頁不用提交到文件系統(tǒng)。tempdb只會(huì)在只會(huì)在臟的緩存頁超過當(dāng)前總量的25%才會(huì)同步刷寫到文件,換句話說在臨時(shí)數(shù)據(jù)庫模式下,事務(wù)提交時(shí)并不總同步臟頁,因此減少了IO數(shù)量,事務(wù)日志也受這種機(jī)制影響,所以在臨時(shí)數(shù)據(jù)庫模式下,事務(wù)日志是不是MEMORY并不重要?;剡^頭來看,內(nèi)存模式則是臨時(shí)模式的一種極致,杜絕所有的IO。這兩種模式都只能存在一個(gè)sqlite3連接,關(guān)閉時(shí)銷毀。
提到內(nèi)存,許多人就會(huì)簡單地理解為,內(nèi)存比磁盤速度快很多,所以內(nèi)存模式比磁盤模式的數(shù)據(jù)庫速度也快很多,甚至有人望文生意就把它變成等同于內(nèi)存數(shù)據(jù)庫。
它并不是為內(nèi)存數(shù)據(jù)庫應(yīng)用而設(shè)計(jì)的,本質(zhì)還是文件數(shù)據(jù)庫。它的數(shù)據(jù)庫存儲(chǔ)文件有將近一半的空間是空置的,這是它的B樹存儲(chǔ)決定的,(2023 勘誤:對(duì)于固定長度記錄,頁面使用率更大化,對(duì)于非自增計(jì)數(shù)鍵的索引,頁面一般會(huì)保留20~扒襪60%的空間,方便插入)請(qǐng)參看上一篇SQLite存儲(chǔ)格式。內(nèi)春睜激存模式只是將數(shù)據(jù)庫存儲(chǔ)文件放入內(nèi)存空間,但并不考慮最有效管理你的內(nèi)存空間,其它臨時(shí)文件也要使用內(nèi)存,事務(wù)回滾日志一樣要生成,只是使用了內(nèi)存空間。它的作用應(yīng)該偏向于臨時(shí)性的用途。
(2023 補(bǔ)充:下面的測(cè)試有局限性,)
我們先來看一下下面的測(cè)試結(jié)果,分別往memory和disk模式的sqlite數(shù)據(jù)庫進(jìn)行1w, 10w以及100w條數(shù)據(jù)的插入,采用一次性提交事務(wù)。另外使用commit_hook捕捉事務(wù)提交次數(shù)。
(注:測(cè)試場(chǎng)景為早襲在新建的數(shù)據(jù)庫做插入操作,所以回滾日志是很小的,并且無需要在插入過程中查找而從數(shù)據(jù)庫加載頁面,因此測(cè)試也并不全面)
內(nèi)存模式
?
磁盤模式
?
在事務(wù)提交前的耗時(shí) (事務(wù)提交后的總耗時(shí)):
1w10w100w
內(nèi)存模式0.04s0.35s3.60s
磁盤模式0.06s (0.27s)0.47s (0.72s)3.95s (4.62s)
可以看到當(dāng)操作的數(shù)據(jù)越少時(shí),內(nèi)存模式的性能提高得越明顯,事務(wù)IO的同步時(shí)間消耗越顯注。
上圖還有一組數(shù)據(jù)比較,就是在單次事務(wù)提交中,如果要為每條插入語句準(zhǔn)備的話
1w10w100w
內(nèi)存模式0.19s1.92s19.46s
磁盤模式0.21s (0.35s)2.06s (2.26s)19.88s (20.41s)
我們從SQLite的設(shè)計(jì)來分析,一次插入操作,SQLite到底做了些什么。首先SQLite的數(shù)據(jù)庫操作是以頁面大小為單位的。在單條記錄插入的事務(wù)中,回滾日志文件被創(chuàng)建。在B樹中查找目標(biāo)頁面,要讀入一些頁面,然后將目標(biāo)頁面以及要修改的父級(jí)頁面寫出到回滾日志。操作目標(biāo)頁面的內(nèi)存映像,插入一條記錄,并在頁面內(nèi)重排序(索引排序,無索引做自增計(jì)數(shù)排序,參看上一篇《SQLite數(shù)據(jù)庫存儲(chǔ)格式》)。最后事務(wù)提交將修改的頁面寫出到數(shù)據(jù)庫文件,成功后再刪除日志文件。在這過程中顯式進(jìn)行了2次寫磁盤(1次寫日志文件,1次同步寫數(shù)據(jù)庫),還有2次隱式寫磁盤(日志文件的創(chuàng)建和刪除),這是在操作目錄節(jié)點(diǎn)。以及為查找加載的頁面讀操作。更加詳細(xì)可以參看官方文檔的討論章節(jié)《Atomic Commit In SQLite》。
如果假設(shè)插入100條記錄,每條記錄都要提交一次事務(wù)就很不劃算,所以需要批量操作來減少事務(wù)提交次數(shù)。假設(shè)頁面大小為4KB,記錄長度在20字節(jié)內(nèi),每頁可放多于200條記錄,一次事務(wù)提交插入100條記錄,假設(shè)這100條記錄正好能放入到同一頁面又沒有產(chǎn)生頁面分裂,這樣就可以在單條記錄插入事務(wù)的IO開銷耗損代價(jià)中完成100條記錄插入。
當(dāng)我們的事務(wù)中,插入的數(shù)據(jù)越多,事務(wù)的IO代價(jià)就會(huì)攤得越薄,所以在插入100w條記錄的測(cè)試結(jié)果中,內(nèi)存模式和磁盤模式的耗時(shí)都十分接近。實(shí)際應(yīng)用場(chǎng)合中也很少會(huì)需要一次插入100w的數(shù)據(jù)。有這樣的需要就不要考慮SQLite。
(補(bǔ)充說明一下,事務(wù)IO指代同步數(shù)據(jù)庫的IO,以及回滾日志的IO,只在本文使用)
除了IO外,還有沒有其它地方也影響著性能。那就是語句執(zhí)行。其實(shí)反觀一切,都是在對(duì)循環(huán)進(jìn)行優(yōu)化。
?
for (i = 0; i
{
exec(“BEGIN TRANS”);
exec(“INSERT INTO …”);
exec(“END TRANS”);
}
?
批量插入:
?
exec(“BEGIN TRANS”);
for (i = 0; i
{
exec(“INSERT INTO …”);
}
exec(“END TRANS”);
?
當(dāng)我們展開插入語句的執(zhí)行
?
exec(“BEGIN TRANS”);
for (i = 0; i
{
// unwind exec(“INSERT INTO …”);
prepare(“INSERT INTO …”);
bind();
step();
finalize();
}
exec(“END TRANS”);
?
又發(fā)現(xiàn)循環(huán)內(nèi)可以移出部分語句
?
exec(“BEGIN TRANS”);
// unwind exec(“INSERT INTO …”);
prepare(“INSERT INTO …”);
for (i = 0; i
{
bind();
step();
}
finalize();
exec(“END TRANS”);
?
這樣就得到了批量插入的最終優(yōu)化模式。
所以對(duì)sql語句的分析,編譯和釋放是直接在損耗CPU,而同步IO則是在饑餓CPU。
請(qǐng)看下圖
?
分別為內(nèi)存模式1w和10w兩組測(cè)試,每組測(cè)試包括4項(xiàng)測(cè)試
1.只編譯一條語句,只提交一次事務(wù)
2.每次插入編譯語句,只提交一次事務(wù)
3.只編譯一條語句,但使用自動(dòng)事務(wù)。
4.每次插入編譯語句,并使用自動(dòng)事務(wù)。
可以看到測(cè)試項(xiàng)目4基本上就是測(cè)試項(xiàng)目2和測(cè)試項(xiàng)目3的結(jié)果的和。
測(cè)試項(xiàng)目1就是批量插入優(yōu)化的最終結(jié)果。
下面是探討內(nèi)存模式的使用:
經(jīng)過上面的分析,內(nèi)存模式在批量插入對(duì)比磁盤模式提升不是太顯注的,請(qǐng)現(xiàn)在開始關(guān)注未批量插入的結(jié)果。
下面給出的是磁盤模式0.1w和0.2w兩組測(cè)試,每組測(cè)試包括4項(xiàng)測(cè)試
?
可以看到在非批量插入情況,sqlite表現(xiàn)很差要100秒來完成1000次單條插入事務(wù),但絕非sqlite很吃力,因?yàn)閏pu在空載,IO阻塞了程序。
再來看內(nèi)存模式20w測(cè)試
?
可以看到sqlite在內(nèi)存模式,即使在20w次的單條插入事務(wù),其耗時(shí)也不太遜于磁盤模式100w插入一次事務(wù)。
0.1w0.2w20w
內(nèi)存模式(非批量插入).87s
磁盤模式(非批量插入)97.4s198.28s
編譯1次插入語句每次插入編譯1次語句
內(nèi)存模式(20w,20w次事務(wù))11.10s15.87s
磁盤模式(100w,1次事務(wù))4.62s20.41s
關(guān)于sqlite數(shù)據(jù)庫執(zhí)行效率的介紹到此就結(jié)束了,不知道你從中找到你需要的信息了嗎 ?如果你還想了解更多這方面的信息,記得收藏關(guān)注本站。
香港服務(wù)器選創(chuàng)新互聯(lián),香港虛擬主機(jī)被稱為香港虛擬空間/香港網(wǎng)站空間,或者簡稱香港主機(jī)/香港空間。香港虛擬主機(jī)特點(diǎn)是免備案空間開通就用, 創(chuàng)新互聯(lián)香港主機(jī)精選cn2+bgp線路訪問快、穩(wěn)定!
分享名稱:提升sqlite數(shù)據(jù)庫執(zhí)行效率的方法探究(sqlite數(shù)據(jù)庫執(zhí)行效率)
URL網(wǎng)址:http://fisionsoft.com.cn/article/djihips.html


咨詢
建站咨詢
