SQLite學習筆記(十二)&&虛擬機指令

来源:http://www.cnblogs.com/cchust/archive/2016/01/21/5143666.html
-Advertisement-
Play Games

上篇文章簡單討論了虛擬機的原理,這篇文章我們詳細討論下指令,具體從幾種典型的SQL語句來看看每種SQL對應的指令流,以及每個指令的含義。通過explain語句,可以看到語句對應的指令流;通過pragma vdbe_trace=on指令,我們甚至可以得到語句對應的指令執行流程,包括跳轉等。測試表結.....


     上篇文章簡單討論了虛擬機的原理,這篇文章我們詳細討論下指令,具體從幾種典型的SQL語句來看看每種SQL對應的指令流,以及每個指令的含義。通過explain語句,可以看到語句對應的指令流;通過pragma vdbe_trace=on指令,我們甚至可以得到語句對應的指令執行流程,包括跳轉等。
測試表結構

CREATE TABLE t1(
  id integer primary key autoincrement, 
  user_id int, 
  c1 varchar(1000), 
  c2 varchar(1000)
);

測試語句
(1)INSERT

sqlite> explain insert into t1(user_id,c1,c2) values(1111,'abc','abc');
0|Init|0|17|0||00|Start at 17
1|OpenWrite|0|5|0|4|00|root=5 iDb=0; t1
2|NewRowid|0|4|2||00|r[4]=rowid
3|MemMax|2|4|0||00|r[2]=max(r[2],r[4])
4|SoftNull|5|0|0||00|r[5]=NULL
5|Integer|1111|6|0||00|r[6]=1111
6|String8|0|7|0|abc|00|r[7]='abc'
7|String8|0|8|0|abc|00|r[8]='abc'
8|MakeRecord|5|4|9|DDBB|00|r[9]=mkrec(r[5..8])
9|Insert|0|9|4|t1|1b|intkey=r[4] data=r[9]
10|Close|0|0|0||00|
11|OpenWrite|0|3|0|2|00|root=3 iDb=0; sqlite_sequence
12|NotNull|3|14|0||00|if r[3]!=NULL goto 14
13|NewRowid|0|3|0||00|r[3]=rowid
14|MakeRecord|1|2|10||00|r[10]=mkrec(r[1..2])
15|Insert|0|10|3||08|intkey=r[3] data=r[10]
16|Halt|0|0|0||00|
17|Transaction|0|1|4|0|01|
18|TableLock|0|5|1|t1|00|iDb=0 root=5 write=1
19|TableLock|0|3|1|sqlite_sequence|00|iDb=0 root=3 write=1
20|OpenRead|0|3|0|2|00|root=3 iDb=0; sqlite_sequence
21|Null|0|2|3||00|r[2..3]=NULL
22|String8|0|1|0|t1|00|r[1]='t1'
23|Rewind|0|31|0||00|
24|Column|0|0|2||00|r[2]=
25|Ne|1|29|2||10|if r[1]!=r[2] goto 29
26|Rowid|0|3|0||00|r[3]=rowid
27|Column|0|1|2||00|r[2]=
28|Goto|0|31|0||00|
29|Next|0|24|0||00|
30|Integer|0|2|0||00|r[2]=0
31|Close|0|0|0||00|
32|Goto|0|1|0||00|

通過explain我們得到了語句對應的指令流,該語句總共包含了32條指令,下麵我們逐條來說明指令的含義。

 

指令

含義

0

Init|0|17|0||00|Start at 17

指令從P2(17)開始

1

OpenWrite|0|5|0|4|00|root=5 iDb=0; t1

打開表t1讀寫游標cursor0,P4,表示總共有4列

2

NewRowid|0|4|2||00|r[4]=rowid

生成一個newRowid,寫入P2寄存器,P3寄存器存儲的是目前最大值,當rowid達到最大值,則SQLITE_FULL error。

3

MemMax|2|4|0||00|r[2]=max(r[2],r[4])

取出sqlite_sequence裡面和表裡面記錄的最大值

4

SoftNull|5|0|0||00|r[5]=NULL

 初始化r[5]為null,rowid列

5

Integer|1111|6|0||00|r[6]=1111

 設置寄存器r[6]為1111

6

String8|0|7|0|abc|00|r[7]='abc'

 設置寄存器r[7]為abc

7

String8|0|8|0|abc|00|r[8]='abc'

 設置寄存器r[8]為abc

8

MakeRecord|5|4|9|DDBB|00|r[9]=mkrec(r[5..8])

生成t1表記錄

將寄存器r[5..8]的內容轉為記錄格式,存入r[9],P2指定長度為4。

9

Insert|0|9|4|t1|1b|intkey=r[4] data=r[9]

插入

key在r[4]中,data在r[9]寄存器中

10

Close|0|0|0||00|

關閉游標

11

OpenWrite|0|3|0|2|00|root=3 iDb=0; sqlite_sequence

 打開寫游標

12

NotNull|3|14|0||00|if r[3]!=NULL goto 14

 r[3]不為null,則跳轉14

13

NewRowid|0|3|0||00|r[3]=rowid

 生成新的rowid

14

MakeRecord|1|2|10||00|r[10]=mkrec(r[1..2])

生成sqlite_sequence記錄 

生成記錄,r[1]=t1,r[2]=seq

15

Insert|0|10|3||08|intkey=r[3] data=r[10]

插入 

key=r[3],data=r[10]

16

Halt|0|0|0||00|

 終止

17

Transaction|0|1|4|0|01|

打開一個新事務,創建回滾日誌文件

18

TableLock|0|5|1|t1|00|iDb=0 root=5 write=1

上t1表鎖(僅用於shared-cache)

19

TableLock|0|3|1|sqlite_sequence|00|iDb=0 root=3 write=1

 上sqlite_sequence表鎖

20

OpenRead|0|3|0|2|00|root=3 iDb=0; sqlite_sequence

打開sqlite_sequence表,P4,表示總共2列

21

Null|0|2|3||00|r[2..3]=NULL

初始化寄存器為NULL

22

String8|0|1|0|t1|00|r[1]='t1'

 設置r[1]為t1

23

Rewind|0|31|0||00|

重置游標cursor P1,游標指向索引的第一個位置,如果tree為空,則跳轉到31,否則執行下麵的指令

24

Column|0|0|2||00|r[2]=

獲取cusor P1指向記錄的P2th列,即sqlite_sequence的name列,結果存在r[2]中

25

Ne|1|29|2||10|if r[1]!=r[2] goto 29

如果sqlite_sequence表中記錄與當前的表名不一致,跳轉到29

26

Rowid|0|3|0||00|r[3]=rowid

獲取當前記錄的rowid

27

Column|0|1|2||00|r[2]=

獲取當前記錄的第1列,結果存放在r[2]中,sqlite_sequence的第一列是seq值

28

Goto|0|31|0||00|

跳轉到31

29

Next|0|24|0||00|

游標往後移,如果還有記錄,則跳轉到P2(24),否則繼續往後執行。

30

Integer|0|2|0||00|r[2]=0

 這是r[2]為0

31

Close|0|0|0||00|

關閉sqlite_sequence表的游標

32

Goto|0|1|0||00|

跳轉到1,開始執行插入表t1

      通過pragma命令,設置vdbe_trace為on可以看到SQL語句對應的指令流是如何運行的,具體如下:可以看到,指令並不是順序執行的,而是存在跳轉,具體的執行順序,由代碼生成器生成指令流和指令的內容決定。

sqlite> pragma vdbe_trace=on;
sqlite> insert into t1(user_id,c1,c2) values(1111,'abc','abc');
SQL: [insert into t1(user_id,c1,c2) values(1111,'abc','abc');]
VDBE Trace:
0 Init 0 17 0 00 Start at 17
17 Transaction 0 1 4 0 01 
18 TableLock 0 5 1 t1 00 iDb=0 root=5 write=1
19 TableLock 0 3 1 sqlite_sequence 00 iDb=0 root=3 write=1
20 OpenRead 0 3 0 2 00 root=3 iDb=0; sqlite_sequence
21 Null 0 2 3 00 r[2..3]=NULL
REG[2] = NULL
22 String8 0 1 0 t1 00 r[1]='t1'
REG[1] = t2[t1](8)
23 Rewind 0 31 0 00 
24 Column 0 0 2 00 r[2]=
REG[2] = s4[user](8)
25 Ne 1 29 2 10 if r[1]!=r[2] goto 29
REG[1] = t2[t1](8)
REG[2] = s4[user](8)
29 Next 0 24 0 00 
24 Column 0 0 2 00 r[2]=
REG[2] = s6[orders](8)
25 Ne 1 29 2 10 if r[1]!=r[2] goto 29
REG[1] = t2[t1](8)
REG[2] = s6[orders](8)
29 Next 0 24 0 00 
24 Column 0 0 2 00 r[2]=
REG[2] = s2[t1](8)
25 Ne 1 29 2 10 if r[1]!=r[2] goto 29
REG[1] = t2[t1](8)
REG[2] = s2[t1](8)
26 Rowid 0 3 0 00 r[3]=rowid
REG[3] = i:3
27 Column 0 1 2 00 r[2]=
REG[2] = i:113
28 Goto 0 31 0 00 
31 Close 0 0 0 00 
32 Goto 0 1 0 00 
1 OpenWrite 0 5 0 4 00 root=5 iDb=0; t1
2 NewRowid 0 4 2 00 r[4]=rowid
REG[2] = i:113
REG[4] = i:114
3 MemMax 2 4 0 00 r[2]=max(r[2],r[4])
REG[4] = i:114
4 SoftNull 5 0 0 00 r[5]=NULL
5 Integer 1111 6 0 00 r[6]=1111
REG[6] = i:1111
6 String8 0 7 0 abc 00 r[7]='abc'
REG[7] = t3[abc](8)
7 String8 0 8 0 abc 00 r[8]='abc'
REG[8] = t3[abc](8)
8 MakeRecord 5 4 9 DDBB 00 r[9]=mkrec(r[5..8])
REG[9] = s13[05000213130457616263616263......Wabcabc](8)
9 Insert 0 9 4 t1 1B intkey=r[4] data	   

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 由於本人也是邊學邊寫,因此整理的比較亂,下麵放出我例子的完整代碼,方便大家交流測試,如有問題歡迎評論首先,表格採用的是BootStrap樣式編輯的,主要使用的是angularjs,為了方便也有jQuery的方法,在測試時需自行引入bootstrap,angularjs和jq的文件。 整體代碼預覽:H...
  • 在ng-repeat中使用ng-model時會有許多問,有的人碰到無法獲取綁定的數據內容,有的人遇到改動綁定的數據內容時所有迴圈生成的內容一起改變。上面的問題我在開發時也遇到過,但是解決後我卻怎麼也還原不了那種情況了,只能先簡單介紹一下無法獲取的情景該如何解決。例如:html: ...
  • 前言 近來由於工作需要,需要提取某些城市的經緯度坐標,稍微搜索了一下,發現百度地圖和高德地圖都提供了相關的函數和例子.那麼剩餘的工作也就比較簡單了,保存坐標,然後轉換為WGS坐標,這樣才能和現有的GPS數據以及地圖匹配.主要問題和解決方法本地保存文件跨瀏覽器支持 由於安全的原因,JavaScript...
  • 寫網頁的時候很多情況需要對圖片進行操作,如何在不進行專業的美工裁切操作的情況下而讓自己的素材度達到最大的滿意度呢,這是一個問題,對於懶得開ps切圖的我,通常會直接在網路上download一張圖片,直接拖到html里,這就需要對圖片的css樣式進行一些調整,鑒於我總是記不住一些樣式屬性而無法讓圖片.....
  • 1 2 3 4 5 6 7 8 27 28 dian29 30 今天開始學習 dojo 目的是學習 arc gis api for jsrequire 方法:引入組件和模塊on 方法:綁定...
  • 。。。。
  • 首先說明》 FEDERATED存儲引擎訪問在遠程資料庫的表中的數據,而不是本地的表。這個特性給某些開發應用帶來了便利,你可以直接在本地構建一個federated表來連接遠程數據表,配置好了之後本地表的數據可以直接跟遠程數據表同步。實際上這個引擎裡面是不真實存放數據的,所需要的數據都是連接到其他MyS...
  • 機器學習很多場景中會用到放回采樣,比如bagging方法。
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...