1. 程式人生 > >SQLite 查詢處理及優化

SQLite 查詢處理及優化

查詢處理及優化是關係資料庫得以流行的根本原因,也是關係資料庫系統最核心的技術之一。SQLite的查詢處理模組非常的精緻,而且很容易移植到不支援SQL的儲存引擎,Berkeley DB最新的版本已經將其完整的移植過來。本文將簡要的討論一下SQLite的查詢處理及優化。
     查詢處理一般來說,包括詞法分析、語法分析、語義分析、生成執行計劃以及計劃的執行幾個部分。SQLite的詞法分析器是手工寫的,語法分析器由Lemon生成,語義分析主要的進行語義方面的一些檢查,比如table是否存在等。而執行計劃的生成及執行是最核心的兩部分,也是相對比較複雜、有點技術含量的東西。SQLite的執行計劃採用了虛擬機器的思想,實際上,這種基於虛擬機器的思想並非SQLite所獨有,但是,SQLite將其發揮到了極致,它生成的執行計劃非常詳細,而且很容易讀(在這裡,我不得不佩服D. Richard Hipp在編譯理論方面的功底)。


1、語法分析——語法樹
詞法分析本身比較簡單,這裡就不談了。語法分析的主要任務就是對使用者輸入的SQL語句進行語法檢查,然後生成一個包含所有資訊的語法樹。對於SELECT語句,這個語法樹最終由結構體Select表示:

複製程式碼 程式碼 struct Select {
  ExprList 
*pEList;      /* The fields of the result */
  u8 op;                 
/* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */char affinity;         /* MakeRecord with this affinity for SRT_Set 
*/
  u16 selFlags;          
/* Various SF_* values */
  SrcList 
*pSrc;         /* The FROM clause */
  Expr 
*pWhere;          /* The WHERE clause */
  ExprList 
*pGroupBy;    /* The GROUP BY clause */
  Expr 
*pHaving;         /* The HAVING clause */
  ExprList 
*pOrderBy;    /* The ORDER BY clause */
  Select 
*pPrior;        /* Prior select in a compound select statement */
  Select 
*pNext;         /* Next select to the left in a compound */
  Select 
*pRightmost;    /* Right-most select in a compound select statement */
  Expr 
*pLimit;          /* LIMIT expression. NULL means not used. */
  Expr 
*pOffset;         /* OFFSET expression. NULL means not used. */int iLimit, iOffset;   /* Memory registers holding LIMIT & OFFSET counters */int addrOpenEphm[3];   /* OP_OpenEphem opcodes related to this select */
};
複製程式碼

 該結構體比較簡單,但要注意幾個欄位。pEList輸出結果列的語法樹;pSrc為FROM子句語法樹;pWhere為WHERE部分的語法樹。

select語法分析在最終在sqlite3SelectNew中完成:

程式碼

它主要就是將之前得到的各個子語法樹彙總到Select結構體,並根據該結構,進行接下來語義分析及生成執行計劃等工作。

來看個例子,這個例子貫穿於全文:

複製程式碼  1 explain select s.sname,c.cname,sc.grade from students s join sc join course c on s.sid=sc.sid and sc.cid = c.cid;
 2 0|Trace|0|0|0||00|
 3 1|Goto|0|35|0||00|
 4 //////////////////////////(1)////////////////////////////
 5 2|OpenRead|0|3|0|2|00|students #開啟students表
 6 3|OpenRead|1|7|0|3|00|sc  #開啟sc表
 7 4|OpenRead|3|8|0|keyinfo(2,BINARY,BINARY)|00|sqlite_autoindex_sc_1 #sc的索引
 8 5|OpenRead|2|5|0|2|00|course #course表
 9 6|OpenRead|4|6|0|keyinfo(1,BINARY)|00|sqlite_autoindex_course_1 #course的索引
10 //////////////////////////(2)//////////////////////////////
11 7|Rewind|0|29|0||00| #將遊標p0定位到students表的第一條記錄
12 8|Column|0|0|1||00|students.sid #取出第0列,寫到r1
13 9|IsNull|1|28|0||00|
14 10|Affinity|1|1|0|d|00|
15 11|SeekGe|3|28|1|1|00| #將遊標p3定位到sc索引的>=r1的記錄處
16 12|IdxGE|3|28|1|1|01|
17 13|IdxRowid|3|2|0||00|
18 14|Seek|1|2|0||00|
19 15|Column|3|1|3||00|sc.cid #讀取sc.cid到r3
20 16|IsNull|3|27|0||00|
21 17|Affinity|3|1|0|d|00|
22 18|SeekGe|4|27|3|1|00| #將遊標p4定位到course索引的>=r3的記錄處
23 19|IdxGE|4|27|3|1|01|
24 20|IdxRowid|4|4|0||00|
25 21|Seek|2|4|0||00|
26 ///////////////////////////(3)//////////////////////////////
27 22|Column|0|1|5||00|students.sname #從遊標p0取出第1列 (sname)
28 23|Column|2|1|6||00|course.cname #從遊標p2取出第1列 (cname)
29 24|Column|1|2|7||00|sc.grade #從遊標p1取出第2列(grade)
30 25|ResultRow|5|3|0||00|
31 ///////////////////////////(4)///////////////////////////////
32 26|Next|4|19|0||00|
33 27|Next|3|12|0||00|
34 28|Next|0|8|0||01|
35 29|Close|0|0|0||00|
36 30|Close|1|0|0||00|
37 31|Close|3|0|0||00|
38 32|Close|2|0|0||00|
39 33|Close|4|0|0||00|
40 //////////////////////////(5)//////////////////////////////////
41 34|Halt|0|0|0||00|
42 35|Transaction|0|0|0||00|
43 36|VerifyCookie|0|7|0||00|
44 37|TableLock|0|3|0|students|00|
45 38|TableLock|0|7|0|sc|00|
46 39|TableLock|0|5|0|course|00|
47 40|Goto|0|2|0||00|
48  複製程式碼

 來看看該SQL語句生成的語法樹:

FROM部分:
第一個表項:

表名zName =”stduents”,zAlias=”s”,jointype = 0。
第二個表項:

注意,jointype = 1(JT_INNER)。
第三個表項:


注意,jointype = 1(JT_INNER)。
WHERE部分(結點型別為Expr的一棵二叉樹):

2、生成執行計劃(語法樹到OPCODE)

Select的執行計劃在sqlite3Select中完成:

int sqlite3Select(
  Parse 
*pParse,         /* The parser context */
  Select 
*p,             /* SELECT語法樹 */
  SelectDest 
*pDest      /* 如果處理結果集 */
)

其實,該函式先對SQL語句進行語義分析,然後再進行優化,最後生成執行計劃。

 對於上面要SQL語句,生成的執行計劃(虛擬機器opcode)大致分成5部分,前4部分都在sqlite3Select()中生成,它主要呼叫了以下幾個函式:

 其中(1)、(2)在sqlite3WhereBegin()中生成,(2)即所謂的查詢優化處理;(3)在 selectInnerLoop中生成;(4)在sqlite3WhereEnd中生成;(5)是sqlite3FinishCoding中完成的。後續章節,我將分別分析每一部分。

3、sqlite3WhereBegin
該函式是查詢處理最為核心的函式,它主要完成where部分的優化及相關opcode的生成。

複製程式碼 程式碼 WhereInfo *sqlite3WhereBegin(
  Parse 
*pParse,        /* The parser context */
  SrcList 

相關推薦

SQLite 查詢處理優化

查詢處理及優化是關係資料庫得以流行的根本原因,也是關係資料庫系統最核心的技術之一。SQLite的查詢處理模組非常的精緻,而且很容易移植到不支援SQL的儲存引擎,Berkeley DB最新的版本已經將其完整的移植過來。本文將簡要的討論一下SQLite的查詢處理及優化。

私有網盤nextcloud 12的問題處理優化

nextcloud問題1:如果你在管理界面看到如下提示No memory cache has been configured. To enhance your performance please configure a memcache if available.答:需要我們安裝緩存了,如果你之前是按照我的

mysql聯合查詢分析優化

最近在做報表,跟資料庫打交道的比較多,所以特意來總結一下mysql的聯合查詢; 查詢常用的字句     where(條件查詢)、having(篩選)、group by(分組)、order by(排序)、limit(分頁)、USING(取交集) 1、where常用運算子

Solr查詢配置優化【eDisMax查詢解析器】

一.簡介   Lucene查詢解析器語法支援建立任意複雜的布林查詢,但還有一些缺點,它不是使用者查詢處理的理想解決方案。這裡面最大的問題是Lucene查詢解析器的語法要求嚴格,一旦破壞就會丟擲異常。指望使用者在輸入關鍵詞時能夠理解Lucene查詢語法並始終能輸入完美的查詢表示式,這顯然是不合理的。這意味著,L

數據庫 chapter 9 關系查詢處理查詢優化

規則 查詢優化 選擇 查詢 結合 操作 基本 查詢語句 -1 第九章 關系查詢處理和查詢優化 本章主要關於查詢處理和查詢優化的基本概念,方法和技術。 查詢處理的任務是把用戶提交給RDMS的查詢語句轉換為高效的執行計劃。 查詢處理步驟: 查詢分析 查詢檢查 查詢優化(一般可分

《數據庫系統概論》 -- 9 查詢處理查詢優化

51cto csdn 查詢 優化 安全性 步驟 mysq sql tails 查詢處理步驟 查詢分析 對查詢語句進行掃描、詞法分析和語法分析。 查詢檢查 對合法的

MyBatis SQL分頁處理查詢總數據量

batis ger 分頁 var index add and resultmap ted 查詢數據總數:<select id="selectCount" resultType="java.lang.Integer"> <!-- WAR

第九章 關係查詢處理查詢優化

關係資料庫管理系統查詢處理階段 : 1. 查詢分析 2. 查詢檢查 3. 查詢優化 4. 查詢執行   選擇操作典型實現方法: (1) 全表掃描方法 (Table Scan) 對查詢的基本表順序掃描,逐一檢查每個元組是否滿足選擇條件,把滿足條件的元組作為結果輸出 適合小表,不適合大表

文字處理檔案查詢

title: 文字處理及檔案查詢 date: 2018-10-14 18:18:18 tags: VIM Find Sed 正則表示式 shell指令碼 文字處理及正則表示式 檔案檢視 檔案檢視命令: cat,tac,re

Mysql 多表聯合查詢效率分析優化

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

資料庫系統概論(第九章: 關係查詢處理查詢優化

第9章    關係查詢處理和查詢優化 查詢優化分類 : 代數優化:指關係代數表示式的優化  物理優化:指存取路徑和底層操作演算法的選擇9.1 關係資料庫系統的查詢處理 9.1.1  查詢處理步驟 ※關係資料庫管

MySQL優化(四) 慢查詢的定位優化

啟動 strong ptime pan bsp 回話 query plain ont 一、SQL語句優化的一般步驟: (1)通過 show status 命令了解各種 SQL 的執行效率; (2)定位執行效率較低的 SQL 語句(重點是 Select); (3)通過 exp

關係查詢處理查詢優化

關係資料庫系統的查詢處理 查詢處理步驟 關係資料庫管理系統查詢處理階段 : 1.查詢分析 2.查詢檢查 3.查詢優化 4.查詢執行 實現查詢操作的演算法示例 1.選擇操作的實現 選擇操作典型實現方法: (1) 全表掃描方法 (Table Scan) (2)索引掃描方法 (

迴圈查詢資料的效能問題優化

寫在前言:糟糕的程式碼,對程式碼維護、效能、團隊協作都會造成負面影響,所以,先設計再實現,謀而後動。         這裡的迴圈查詢,指的是在一個for迴圈中,不斷訪問資料庫來查詢資料。在剛接手公司

海量資料處理專題(七)——資料庫索引優化(轉)

索引是對資料庫表中一列或多列的值進行排序的一種結構,使用索引可快速訪問資料庫表中的特定資訊。資料庫索引什麼是索引資料庫索引好比是一本書前面的目錄,能加快資料庫的查詢速度。例如這樣一個查詢:select * from table1 where id=44。如果沒有索引,必須遍歷整個表,直到ID等於44的這一行被

很好的一篇關於MyBatis 多表聯合查詢優化的文章

序 這篇文章我打算來簡單的談談 mybatis 的多表聯合查詢。起初是覺得挺簡單的,沒必要拿出來寫,畢竟 mybatis 這東西現在是個開發的都會用,而且網上的文章也是一搜羅一大堆,根本就用不著我來重複。但是吧,就我前幾天在做一個多表聯合查詢的時候,竟然出了很多

個人機房重構——組合查詢優化

Public Class TemplateMethod '例項化組合查詢的實體 Protected GroupInquire As New Entity.TemplateMethodEntity '定義接收查詢條件的變數 Public txtRemark1 As String

MySQL優化索引優化漢字模糊查詢語句

利用MySQL這種關係型資料庫來做索引,的確有些勉強了,也只能看情況來說了,有些簡單的功能還是可以考慮的。 對於模糊查詢語句,最不利的情況是要like '%key%'這樣的查詢,但是如果是like 'key%'這種情況,那麼mysql的索引在些查詢方式上還是可以優化的。 網

sqlite時間函式時間日期處理

SQLite 包括以下五個時間函式: date(日期時間字串, 修正符, 修正符, ……) time(日期時間字串, 修正符, 修正符, ……) datetime(日期時間字串, 修正符, 修正符, ……) julianday(日期時間字串, 修正符, 修正符, ……) strftime(日期時間格式,

SQL之解決where 1=1 問題優化多條件查詢

Dao中實現多條件查詢。 public List<Product> query(String name ,BigDecimal minSalePrice, BigDecimal maxSalePrice){ QueryR