1. 程式人生 > >踩坑(Running)填坑(ZSSURE):SQLite資料庫操作效率分析

踩坑(Running)填坑(ZSSURE):SQLite資料庫操作效率分析

背景:

之前對於資料庫操作部分大多停留在會使用階段,並未真正考慮過資料庫SQL語句的執行效率問題。近期響應專案組其他成員需要,協助手動修改資料庫。為了提高工作效率編寫了C#測試工程進行相關操作。由於資料庫記錄量較大(超過10K條),在編寫程式過程中發現不同的操作執行效率相差甚遠,特做記錄如下,待後續有時間再深入分析各種資料庫的SQL語句的執行效率。
此次資料庫修改要求涉及到刪除、修改、新增等各種操作,為了簡單對比各種方式下程式的執行效率,只選擇“刪除”操作進行分析。詳情如下:

for迴圈逐條刪除:

起初最直接的思路是通過for迴圈逐個刪除符合條件的記錄,程式碼如下所示:
這裡寫圖片描述

執行效果如下:
這裡寫圖片描述

【知識點補充】:在使用迴圈操作過程中,可以看到在資料庫檔案目錄下生成了XXX.db3-journal的臨時檔案,且大小隨時在變動。(關於journal檔案的描述參見博文journal是SQLite用於回滾操作的暫存文件,當資料庫寫入失敗時,通過journal文件可以復原到未更改之前的資料,通過觀察本機目錄下的journal檔案發現,其大小在隨時變動因此可以猜測,程式碼中迴圈的每一步都在進行資料庫開啟、寫入操作,因此導致耗時超出容忍極限。

使用事務(Transaction):

SQLite預設為每個操作啟動一個事務,也就是上述迴圈程式碼中每一次DELETE以及每一次SELECT都啟動了一個事務,如是“事務開啟+SQL執行+事務關閉”

自然耗費了大量的時間。而手動顯式呼叫SQLiteTransaction將迴圈中的所有SQL操作放到同一個事務中,此時只需要一次事務開啟和關閉的時間即可。(參考博文
另外SQLite的資料庫本質上就是一個磁碟上的檔案,所以一切的資料庫操作都會轉化為對檔案的操作,而頻繁的檔案操作會是一個耗時的I/O過程,極大的影響資料庫的存取速度。
顯式呼叫Transaction的程式碼如下:
這裡寫圖片描述

執行效果為:
這裡寫圖片描述

由此可見,效率較之前“暴力”方式有了明顯數量級的提升,而且在程式執行過程中看不到XXX.db3-journal臨時檔案的生成。

使用LIKE查詢+組合SQL:

再分析一下上述操作流程可以發現,之前的操作是分兩部分完成的:第一步,SELECT查詢滿足要求的待刪除資料;

第二,使用for迴圈逐條DELETE之前SELECT的結果。這兩次操作之間既開闢了多餘的List變數,又重複操作了SQLite資料庫檔案,因此執行效率還有待提高。
這裡用LIKE進行條件查詢,然後使用組合SQL語句直接刪除滿足條件的結果,具體程式碼如下:
這裡寫圖片描述

執行效果如下:
這裡寫圖片描述

由此可見在使用事務Transaction的基礎上,通過改程序序整體流程又一次減少了資料庫開啟、關閉的次數,效率有了進一步的提升。對比上述三種操作效率,結果如下:
這裡寫圖片描述

總結:

隨著ORM技術的出現,對於資料庫的操作越來越簡單,之前也介紹過使用Telerik OpenAccess來進行資料庫相關操作。正是由於諸多新技術的出現使得在專案實際過程中越來越不注重最底層的、最基本的執行效率,對於單條SQL語句、單次操作往往不做任何考慮,直接使用最原始的“野蠻”方式。另外由於之前專案大多是單機版,不會出現WEB應用中海量使用者多併發,因此對於資料庫的執行效率感受就不夠深刻。隨著雲端計算、大資料、分散式的逐漸普及,資料庫技術(尤其是執行效率)會越發重要,【切記】後續在此方面要多用心。




作者:[email protected]
時間:2015/08/16

相關推薦

RunningZSSURESQLite資料庫操作效率分析

背景: 之前對於資料庫操作部分大多停留在會使用階段,並未真正考慮過資料庫SQL語句的執行效率問題。近期響應專案組其他成員需要,協助手動修改資料庫。為了提高工作效率編寫了C#測試工程進行相關操作。由於資料庫記錄量較大(超過10K條),在編寫程式過程中發現不同的操

js byte陣列與16進位制字串互轉對負值

//十六進位制字串轉位元組陣列,跟網上demo一樣 function HexString2Bytes(str) {   var pos = 0;   var len = str.length;   if (len % 2 != 0) { &

正則表示式中的分組 ----

import re string="abcdefg acbdgef abcdgfe cadbgfe" #帶括號與不帶括號的區別 #不帶括號 regex=re.compile("((\w+)\s+\w+)") print(regex.findall(string)) #輸出:[('abcde

flutter 問題集錦各種挖坑的過程

1.新增依賴出現錯誤(eg:english_words) 按照官網的方法新增完依賴是沒有問題的, 把 import 'package:english_words/english_words.dart

Vue2.0 從環境搭建到釋出新手完全攻略

【重點】後來發現這些坑是由於 npm 不是最新的版本3.10.2, 用 npm 3.9.5就會出現以下坑 解決辦法: 請執行以下命令 npm update -g 報錯 Error: Cannot find module 'opn' Error: Cannot find module 'webpack

Matrix-Tree定理sx之前還來得及嗎

從入門到入土:矩陣樹Matrix-Tree定理 參考blog 在正式介紹Matrix_Tree定理之前,我們需要一些前置知識 一些定義與定理 對於一個無向圖GG,ta的生成樹個數等於其基爾霍夫Kirchhhoff矩陣任何一個N−1N−1階主子式的行

2019.9.15 初級資料結構詳解專題待——全篇序

雖然剛剛初三,卻有點要退役的感覺。 記得還在剛剛開始接觸演算法和資料結構時,全班30多人窩在當時只有一個空調的小機房裡,每人抱著一本《資訊學奧賽一本通》(就是常說的橙書),過了2個小時,全班沒有一個人能看懂簡簡單單一個廣搜。 於是我當時就立志,要寫能讓所有人都看懂的資料結構和演算法詳解。如果做不到,那就問

.Net Core Web Api實踐連線Redis時Timeout performing EVAL

前言:前兩篇文章.net core+Redis+IIS+nginx實現Session共享中,介紹了使用Microsoft.Extensions.Caching.Redis實現Session共享的方法,但是高併發時會有連線Redis出現Timeout的問題,這篇文章將介紹該問題的解決方案。 1、環境及工具準備

2014-10-27Android學習------SQLite資料庫操作-----資料庫的建立--SQLiteHelper extends SQLiteOpenHelper

上篇有篇文章講了資料庫的操作  條件是:資料庫已經建好的了,我們只需要從裡面獲取資料(查詢)就可以了, 現在我們來看看第二種資料庫的操作: class SQLiteHelper extends SQLiteOpenHelper 封裝一個繼承SQLiteOpenHelpe

Java筆記ObjectIOStream與IOStream的各種裝飾器先挖個,以後再來詳細

ted objects lose val read thread 環境 valid 序列化對象 Java的序列化和ObjectStream真是一個大坑。。 先不說多線程環境下的問題,在單線程裏,一個Socket只能保持一個ObjectOutputStream,原因好像是

vue元件之間的傳值問題

元件開發中難免會遇到子元件父元件之間以及兄弟元件之間的傳值問題。1、父元件傳值給子元件:如果父元件需要將placeholder值傳給子元件,則在父元件標籤中定義:placeholder="XXX",子元件在data中定義props:['placeholder']來接受,這樣接

[]樹上差分 例題[JLOI2014]松鼠的新家LCA

sca esp name tmp mes font efi 同學 節點 今天算是把LCA這個坑填上了一點點,又復習(其實是預習)了一下樹上差分。其實普通的差分我還是會的,樹上的嘛,也是懂原理的就是沒怎麽打過。 我們先來把樹上差分能做到的看一下: 1.找所有路徑公共覆蓋的

CentOS6.8Linux 安裝Oracle11gR2指南

linux oracle11gR2 安裝 xmanager 字符集設置 安裝前準備: Oracle11gR2安裝介質; linux系統足夠的磁盤空間和內存; linux系統需要有固定ip; Xmanager5(圖形化安裝需要); 依賴包可通過yum方式安裝(需要聯網環境); zip包的解

nginx補充nginx根據上下文跳轉ip或者域名

store access allow tro 跳轉 head 不同的 域名 root 今天有一個需求,要根據上下文調到不同的ip或域名地址,使用上下文做域名跳轉的時候,proxy_pass域名後面一定要帶‘/’否則會把nginx的上下文自動帶入,這樣就行。 location

Openstack系列flat網絡不通

openstack 網絡不通根據openstack手冊部署openstack,部署全部完成,並且沒有任何報錯信息。部署環境為VMware esxi 主機創建VM後。vm卡在bios界面始終無法啟動,vm cpu占用100% (坑一)這種情況需要將計算節點的 (如果無此現象可以不做下面的修改,經測試有的版本的e

【圖論】8月19日前指南自用

自用 排列 歐拉回路 深度優先 獨立 perf 最小 前向星 最短路 Graph 圖論 前向星 圖的割點、橋 雙連通分量 有向圖的強連通分量 無向圖連通分支 拓撲排序 2-SAT 最短路 第K短路 哈密頓路、歐拉路徑、歐拉回路 DAG的深度優先搜索標記 獨立集、團、支配集

數位DP專題持續

www code 記錄 技術分享 hid sizeof tdi div mem 洛谷P3107題面 相對較為模板化的代碼 f[i][j][bo1][bo2]記錄到第i位,數字num出現了x次(j初始為20,若當前數字不為num,j++;否則j--;最後只要記錄j<=2

環境配置近期實測——Ubuntu16.04+CUDA9.0+tensorflow-gpu

u盤 earch 實測 win 1.3 ted 等待 gef kernel 近幾年深度學習在物體檢測方面出現了許多基於不同框架的網絡模型,不同模型需要不同的版本的Python、TensorFlow、Keras、CUDA、cuDNN以及操作系統。不得不說,要把經典物體檢測網絡

Windows下使用OpenSSL生成自簽證書很簡單,一個晚上搞明白的,讓後來者少走彎路

vat 都是 環境 csr 過程 環境變量 crypt 報錯 out 最近在學習中發現openssl 中有個坑,所有的教程都是openssl genrsa -des3 -out private.key 1024,但是產生的證書,npm start 之後就報錯如下: erro

jQuery實現加入購物車飛入動畫效果之開發不停,不止起點位置在Y軸方向位置偏移

開發時為了完成購物車的飛入拋物線,因為懶惰隨大流使用了fly.js外掛,用的時候遇到的兩個坑坑~~ 1. 有滾動條時,拋物體的起點位置在Y軸方向上有位置偏移,偏大 2. 頁面有滾動條時,拋物體的結束位置不一樣,偏大 我:(⊙o⊙)…煩煩的。。。這就是用別人東西的代價 。。。。。。 不