SQLite How it works
SQLite How it works
https://sqlite.org/talks/howitworks-20240624.pdf
in a nutshell
●
An in-process library → not a server
●
One file of ANSI-C code
●
Database is a single file
●
Full-featured SQL
●
Power-safe, serializable transactions
●
Fast
●
Simple API
●
Public domain
App App
DB
DB library
library
App
DB
App
library DB
library
Database
Engine
Database
Content on
Disk
App App
DB
DB library
library
App
DB
App
library DB
library
Database
Engine
Database
Content on
Disk
App App
DB
DB library
library
App
DB
App
library DB
library
Database
Content on
First code: 2000-05-29 Disk
Embedded Client/Server
•
GDBM
•
BerkeleyDB
Non-SQL •
LevelDB
•
RocksDB
•
... and so forth
SQL
One File Of C-code
sqlite3.c
●
257K lines Also: sqlite3.h
●
163K SLOC¹ ● 13.4K lines
●
9.08MB ●
1.8K SLOC
●
0.64MB
https://sqlite.org/fasterthanfs.html
Copyright
“Lite” means “Low Overhead”
not “low capability”
●
1 writer + N concurrent readers
●
1 gigabyte strings and BLOBs
●
281 terabyte databases
●
64-way joins
●
2000 columns per table or index
●
No arbitrary limit on the number of tables or indexes or rows
in a table
Storage Decision Checklist
Remote Data?
Big Data?
Concurrent Writers?
Otherwise
Storage Decision Checklist FAIL!
Remote Data?
Big Data?
Concurrent Writers?
No!
Otherwise fopen()
Found In...
●
Every Android and iOS phone and device
●
Every Mac and Windows10/11 computer
●
Every Firefox, Chrome, and Safari browser
●
Most desktop and phone software applications
●
TVs, smart appliances, automotive “infotainment” systems
●
Countless millions of other applications....
●
More and more of websites
Implementation
Overview
Interface
int main(int argc, char **argv){
sqlite3 *db; /* Database connection */
sqlite3_stmt *pStmt; /* One SQL statement */
int nCol; /* Number of columns in the result set */
db = sqlite3_open(argv[1]);
pStmt = sqlite3_prepare(db, argv[2]);
nCol = sqlite3_column_count(pStmt);
while( sqlite3_step(pStmt)==SQLITE_ROW ){
int i;
printf("Row:\n");
for(i=0; i<nCol; i++){
printf(" %s = %s\n",
sqlite3_column_name(pStmt, i),
sqlite3_column_text(pStmt, i)
);
}
}
sqlite3_finalize(pStmt);
sqlite3_close(db);
return 0; ** Pseudo-code **
}
Ins & Outs
●
SQLite consists of...
– Compiler → translates SQL into bytecode
– Virtual Machine → runs the bytecode
sqlite3_prepare() sqlite3_step()
The SQLite Stack
Parser
Code Generator
Virtual Machine
B-Tree
Pager
OS Interface
The SQLite Stack
●
LALR(1) parser generated Parser
by “Lemon”
Code Generator
●
Reentrant & threadsafe
●
Output: Abstract Syntax Virtual Machine
Tree (AST)
B-Tree
●
Hand-written tokenizer
Pager
OS Interface
The SQLite Stack
●
Semantic analysis Parser
●
AST transformations Code Generator
●
Query planning Virtual Machine
●
Output: “prepared B-Tree
statement” (bytecode)
Pager
OS Interface
Compile SQL Prep'ed Run the
SQL into a program Stmt program Result
Parser
Code Generator
sqlite3_prepare()
Virtual Machine
B-Tree
Pager
OS Interface
Compile SQL Prep'ed Run the
SQL into a program Stmt program Result
Parser
Code Generator
sqlite3_step()
Virtual Machine
B-Tree
Pager
OS Interface
The SQLite Stack
●
Bytecode interpreter Parser
●
3-address, 5-operand Code Generator
register machine
Virtual Machine
●
Big switch statement on
the opcode and inside a B-Tree
loop. Pager
●
Special opcodes designed OS Interface
to help implement SQL
statements
EXPLAIN SELECT price FROM tab WHERE fruit='Orange';
Indentation
Indentationshowing
showingloop
loopstructure
structureisisinserted
insertedbybythe
thedisplay
displaylogic
logicinin
the
thecommand-line
command-lineshell
shelland
andisisnot
notpart
partofofthe
theactual
actualbytecode.
bytecode.
The
The“opcode”
“opcode”isisreally
reallyaasmall
smallinteger.
integer.
“Debug” version of the command-
line tool for SQLite
●
Browser: https://sqlite.org/fiddle-debug
●
Linux:
– apt install build-essentials tcl-dev
– ./configure --enable-debug && make
sqlite3
●
Mac:
– Install XCode and TCL
– ./configure --enable-debug && make
sqlite3
●
Windows:
https://sqlite.org/src/doc/trunk/doc/compile-
for-windows.md
Extra debugging commands
Code Generator
Virtual Machine
B-Tree
OS Interface
The SQLite Stack
Serverless Client/Server
•
GDBM
BerkeleyDB Parser
Non-SQL •
LevelDB
•
RocksDB
•
... and so forth
Code Generator
SQL
Virtual Machine
B-Tree
OS Interface
The SQLite Stack
Parser
Code Generator
Virtual Machine
●
Concurrent read/write of the Pager
same table using separate
cursors OS Interface
The SQLite Stack
●
Atomic commit and rollback Parser
●
Uniform size pages numbered
from 1 Code Generator
●
512 to 65536 bytes per page Virtual Machine
●
No interpretation of page content
B-Tree
●
Cache
●
Concurrency control Pager
OS Interface
The SQLite Stack
●
Platform-specific interface Parser
to the OS
Code Generator
●
Run-time changeable
Virtual Machine
●
Portability layer
B-Tree
●
read()/write() or mmap()
Pager
●
https://sqlite.org/vfs.html
●
Direct I/O to hardware: OS Interface
test_onefile.c
os_unix.c
os_win.c
VFS Shims
●
Inserted in between Pager Parser
and OS Interface
Code Generator
●
Encryption
Virtual Machine
●
Compression
B-Tree
●
Logging
Pager
●
Testing & fault injection
Shim
●
And so forth...
OS Interface
More Detail
The SQLite Stack
●
Power-safe transactions Parser
– Rollback mode
Code Generator
– Write-ahead log
(WAL) mode Virtual Machine
●
Concurrency control B-Tree
●
In-memory cache of disk
Pager
content
OS Interface
Rollback Journaling
User OS
Space Cache Disk
Rollback Journaling
User OS
Space Cache Disk
shared
Rollback Journaling
User OS
Space Cache Disk
shared
Rollback Journaling
User OS
Space Cache Disk
reserved
Rollback Journaling
User OS
Space Cache Disk
reserved
database-journal
Rollback Journaling
User OS
Space Cache Disk
reserved
database-journal
Rollback Journaling
User OS
Space Cache Disk
reserved
database-journal
exclusive
database-journal
Rollback Journaling
User OS
Space Cache Disk
exclusive
database-journal
Rollback Journaling
User OS
Space Cache Disk
exclusive
database-journal
exclusive
database-journal
Rollback Mode Crash Recovery
User OS
Space Cache Disk
database-journal
Rollback Mode Crash Recovery
User OS
Space Cache Disk
shared
Hot journal
database-journal
Rollback Mode Crash Recovery
User OS
Space Cache Disk
exclusive
database-journal
Rollback Mode Crash Recovery
User OS
Space Cache Disk
exclusive
database-journal
Write-Ahead Log
User OS
Space Cache Disk
shared
Write-Ahead Log
User OS
Space Cache Disk
shared
Write-Ahead Log
User OS
Space Cache Disk
shared
database-wal
•
Write-Ahead Log
User OS
Space Cache Disk
Another
Process
shared
database-wal
•
Write-Ahead Log
User OS
Space Cache Disk
Another
Process
shared
database-wal
•
Write-Ahead Log
User OS
Space Cache Disk
Another
Process
shared
database-wal
•
•
Write-Ahead Log
User OS
Space Cache Disk
Another
Process
shared
database-wal
• •
• •
shared
database-wal
• •
• •
Checkpoint
OS
Cache Disk
shared
truncate
truncate
database-wal
The B-tree Layer
●
Multiple B-trees per file Parser
●
B+trees with 64-bit integer
keys and arbitrary blob content Code Generator
●
B-trees with arbitrary blob keys Virtual Machine
and no content
B-Tree
Pager
OS Interface
Logical View of SQL Table Storage
Root page
Integer key
Some keys appear more than Non-leaf pages hold only keys
once in the tree.
Between 50 and 8000
keys/page depending
on page size.
Integer key
Integer key
Binary content
Surprising Attributes of Overflow
●
Multi-megabyte
BLOBs and strings
work well.
●
Faster to store
BLOBs in the
database than directly
on disk for sizes up to
about 100K.
B-tree Page Layout
Header contains:
8- or 12-byte page header • Page type
• Number of entries
Offset to content - 2 bytes per entry • Free space info
• Right-most child pointer
●
SQL tables ●
SQL indexes
●
Integer keys ●
Arbitrary keys
●
Data in leaves ●
No data (key=data)
●
Some keys on ●
Keys unique across
more than one all pages
page
Mapping B-trees Into Pages
Page 1
Page 2
Page 3
Page 4
Page 5
Page 6
Page 7
Page 8
Page 9
Page 10
Page 11
Page 12
Page 13
Page 14
sqlite_schema
CREATE TABLE sqlite_schema(
type text,
name text,
tbl_name text,
rootpage integer,
sql text
);
●
Defines the “tuple format” Code Generator
Virtual Machine
Tuple Format
B-Tree
Pager
OS Interface
0 to 127
128 to 16383
16384 to 2097151
2097152 to 268435455
268435456 to 34359738367
34359738368 to 4398046511103
4398046511104 to 562949953421311
562949953421312 to 72057594037927935
Less than 0 or greater than 72057594037927935
Tuple Format
Header Content
header content
04 02 00 17 00 b1 68 65 6c 6c 6f
OS Interface
build.c
delete.c
expr.c
insert.c
update.c
AST Transformations
●
Resolve table and column names and
expand VIEWs
●
Expand “*” in “SELECT * FROM ...”
●
Move all constraints into the WHERE clause
●
“Flatten” subqueries into outer queries
●
Push WHERE clause terms in outer queries
down into subqueries
●
Outer join strength reduction
●
And so forth....
Move Constraints Into WHERE
●
NATURAL JOIN → JOIN USING
●
JOIN USING → JOIN ON
●
ON → WHERE
Expand view V1
OS Interface
build.c
delete.c
expr.c
insert.c
update.c
Left-to-Right Grouping Only
FROM
LEFT JOIN
JOIN D
JOIN C
A B
select * from A join B join C left join (D join E)
FROM
LEFT JOIN
JOIN JOIN
JOIN C D E
A B
Transform Into This
FROM
LEFT JOIN
JOIN Materialize
JOIN C JOIN
A B E
D
Schematic Of The Bytecode We Are
Trying To Generate:
Open cursors for each
Cursor for the table itself, or
table in the FROM clause an index on the table, or both.
One or two cursors per table.
Position cursors to the
first result row
Output the row, or send the row
to a sorter, or send it to an
Use the cursors to create aggregator, or store it in a table,
one row of result or ....
Found another
combination of
cursor positions
Advance to next row
No more
Stop
To See The Bytecode For The Next Slide:
●
Go to https://sqlite.org/fiddle
●
Enter: CREATE TABLE t1(a,b);
CREATE TABLE t2(c,d);
CREATE TABLE t3(e,f);
PRAGMA automatic_index=off;
EXPLAIN
SELECT a,c,e Disables
FROM t1 JOIN t2 ON b=c query-time
JOIN t3 ON e=d; indexes
SELECT t1.a, t2.c, t3.e
FROM t1 JOIN t2 ON t1.b=t2.c
JOIN t3 ON t3.e=t2.d
Grayed content appears
only when using special
addr opcode p1 p2 p3 p4 p5 comment compile-time options
---- ------------- ---- ---- ---- ------------- -- -------------
0 Init 0 24 0 0 Start at 24 intended for debugging
1
2
OpenRead
OpenRead
0
1
2
3
0
0
2
2
0
0
root=2 iDb=0; t1
root=3 iDb=0; t2
and analysis.
3 OpenRead 2 4 0 1 0 root=4 iDb=0; t3
4 Explain 4 0 0 SCAN t1 0
5 Rewind 0 23 0 0
6 Explain 6 0 0 SCAN t2 0
7 Rewind 1 23 0 0
8 Column 0 1 1 0 r[1]= cursor 0 column 1
9 Column 1 0 2 0 r[2]= cursor 1 column 0
10 Ne 2 21 1 BINARY-8 81 if r[1]!=r[2] goto 21
11 Explain 11 0 0 SCAN t3 0
12 Rewind 2 23 0 0
13 Column 2 0 2 0 r[2]= cursor 2 column 0
14 Column 1 1 1 0 r[1]= cursor 1 column 1
15 Ne 1 20 2 BINARY-8 81 if r[2]!=r[1] goto 20
16 Column 0 0 3 0 r[3]= cursor 0 column 0
17 Column 1 0 4 0 r[4]= cursor 1 column 0
18 Column 2 0 5 0 r[5]= cursor 2 column 0
19 ResultRow 3 3 0 0 output=r[3..5]
20 Next 2 13 0 1
21 Next 1 8 0 1
22 Next 0 6 0 1
23 Halt 0 0 0 0
24 Transaction 0 0 3 0 1 usesStmtJournal=0
25 Goto 0 1 0 0
In this case, the best plan is: D(5), B(3), A(1), C(9)
Query Planning Example #3
addr
----
opcode
-------------
p1
----
p2
----
p3
----
p4
-------------
p5 comment
-- -------------
Open cursors
0 Init 0 31 0 0 Start at 31
1 OpenRead 2 5 0 5 0 root=5 iDb=0; D
2 OpenRead 4 11 0 k(2,,) 2 root=11 iDb=0; D2
3 OpenRead 1 3 0 4 0 root=3 iDb=0; B
4 OpenRead 0 2 0 2 0 root=2 iDb=0; A Loop over all
5 OpenRead 3 4 0 0 0 root=4 iDb=0; C
6 Explain 6 0 0 SEARCH D USING INDEX D2 (a2=?) 0 D.a2=25
7 Integer 25 1 0 0 r[1]=25
8 SeekGE 4 30 1 1 0 key=r[1]
9 IdxGT 4 30 1 1 0 key=r[1] Find B where
10
11
DeferredSeek
Explain
4
11
0
0
2
0
0 Move 2 to 4.rowid if needed
SEARCH B USING INTEGER PRIMARY KEY (rowid=?) 0
B.id=D.b_id
12 Column 2 3 2 0 r[2]= cursor 2 column 3
13 SeekRowid 1 29 2 0 intkey=r[2] Skip if B.a3<>12
14 Column 1 2 3 0 r[3]= cursor 1 column 2
15 Ne 4 29 3 BINARY-8 81 if r[3]!=r[4] goto 29
16 Explain 16 0 0 SEARCH A USING INTEGER PRIMARY KEY (rowid=?) 0 Find A where
17
18
Column
SeekRowid
1
0
3
29
5
5
0
0
r[5]= cursor 1 column 3
intkey=r[5]
A.id=B.a_id
19 Column 0 1 3 0 r[3]= cursor 0 column 1
20 Ne 6 29 3 BINARY-8 81 if r[3]!=r[6] goto 29 Skip if A.a1<>42
21 Explain 21 0 0 SEARCH C USING INTEGER PRIMARY KEY (rowid=?) 0
22 Column 2 4 7 0 r[7]= cursor 2 column 4
23 SeekRowid 3 29 7 0 intkey=r[7]
24 Column 0 1 8 0 r[8]= cursor 0 column 1 Find C where
25
26
Column
Column
1
1
1
2
9
10
0
0
r[9]= cursor 1 column 1
r[10]= cursor 1 column 2 C.id=D.c_id
27 Column 2 2 11 0 r[11]= cursor 2 column 2
28 ResultRow 8 4 0 0 output=r[8..11]
29 Next 4 9 1 0
30 Halt 0 0 0 0 Generate one
31 Transaction 0 0 10 0 1 usesStmtJournal=0
32 Integer 12 4 0 0 r[4]=12 result row
33 Integer 42 6 0 0 r[6]=42
34 Goto 0 1 0 0
Query Planning Example #3
SELECT A.a1, B.a2, B.a3, D.a4 Id Term Prereq Type Cost
FROM A JOIN B ON A.id=B.a_id X A - query-time index on A.a1 271,53,43
JOIN D ON D.b_id=B.id
X A - full-table scan 0,216,180
JOIN C ON C.id=D.c_id
WHERE A.a1=42 0 A - index on A.a1 0, 56, 33
AND B.a3=12 1 A B primary-key 0, 45, -1
AND D.a2=25;
X B - query-time index on B.a3 271,53,43
X B A query-time index on B.a_id 271,53,43
X B - full-table scan 0,216,180
2 B - index on B.a3 0, 62, 33
3 B D primary-key 0, 45, -1
4 B A index on B.a_id 0, 62, 32
X D - query-time index on D.a2 271,53,43
X D B query-time index on D.b_id 271,53,43
X D C query-time index on D.c_id 271,53,43
X D - full-table scan 0, 216, 200
5 D - index on D.a2 0, 62, 33
6 D B index on D.b_id 0, 62, 33
7 D C index on D.c_id 0, 62, 33
8 C - full-table scan 0, 216, 200
9 C D primary-key 0, 45, 0
Query Planning Example #3
SELECT A.a1, B.a2, B.a3, D.a4 Id Term Prereq Type Cost
FROM A JOIN B ON A.id=B.a_id
0 A - index on A.a1 0, 56, 33
JOIN D ON D.b_id=B.id
JOIN C ON C.id=D.c_id 1 A B primary-key 0, 45, -1
WHERE A.a1=42 2 B - index on B.a3 0, 62, 33
AND B.a3=12
AND D.a2=25; 3 B D primary-key 0, 45, -1
4 B A index on B.a_id 0, 62, 32
5 D - index on D.a2 0, 62, 33
6 D B index on D.b_id 0, 62, 33
7 D C index on D.c_id 0, 62, 33
8 C - full-table scan 0, 216, 200
9 C D primary-key 0, 45, 0
Query Planning Example #3
Id T Pre Type Cost
0 A - index on A.a1 0, 56, 33
1 A B primary-key 0, 45, -1
2 B - index on B.a3 0, 62, 33
3 B D primary-key 0, 45, -1
4 B A index on B.a_id 0, 62, 32
5 D - index on D.a2 0, 62, 33
6 D B index on D.b_id 0, 62, 33
7 D C index on D.c_id 0, 62, 33
8 C - full-table scan 0, 216, 200
9 C D primary-key 0, 45, 0
Query Planning Example #3
Id T Pre Type Cost
0 A - index on A.a1 0, 56, 33
1 A B primary-key 0, 45, -1
2 B - index on B.a3 0, 62, 33
3 B D primary-key 0, 45, -1
4 B A index on B.a_id 0, 62, 32
5 D - index on D.a2 0, 62, 33
6 D B index on D.b_id 0, 62, 33
7 D C index on D.c_id 0, 62, 33
8 C - full-table scan 0, 216, 200
9 C D primary-key 0, 45, 0
Paths of length 1:
Path Cost
A(0) 56,33 ●
All possible outer loops
B(2) 62,33 ●
WhereLoops without prerequisites
D(5) 62,33
C(8) 216,200
Query Planning Example #3
Id T Pre Type Cost Paths of length 2:
0 A - index on A.a1 0, 56, 33
1 A B primary-key 0, 45, -1 Path Cost
2 B - index on B.a3 0, 62, 33 A(0) B(2)
A(0), 33
96, 66
3 B D primary-key 0, 45, -1
B(2) B(4)
A(0), 33
96, 65
4 B A index on B.a_id 0, 62, 32
A(0),
D(5) D(5) 96, 66
33
5 D - index on D.a2 0, 62, 33
6 D B index on D.b_id 0, 62, 33 A(0),
C(8) C(8) 249, 233
216
7 D C index on D.c_id 0, 62, 33 ... ...
8 C - full-table scan 0, 216, 200
9 C D primary-key 0, 45, 0
Paths of length 1:
Path Cost
A(0) 56,33
B(2) 62,33
D(5) 62,33
C(8) 216,200
Query Planning Example #3
Id T Pre Type Cost Paths of length 2:
0 A - index on A.a1 0, 56, 33
1 A B primary-key 0, 45, -1 Path Cost
2 B - index on B.a3 0, 62, 33 A(0) B(2)
A(0), 33
96, 66 X
3 B D primary-key 0, 45, -1
B(2) B(4)
A(0), 33
96, 65
4 B A index on B.a_id 0, 62, 32
A(0),
D(5) D(5) 96, 66
33
5 D - index on D.a2 0, 62, 33
6 D B index on D.b_id 0, 62, 33 A(0),
C(8) C(8) 249, 233
216
7 D C index on D.c_id 0, 62, 33 ... ...
8 C - full-table scan 0, 216, 200
9 C D primary-key 0, 45, 0
Paths of length 1:
Path Cost
A(0) 56,33
B(2) 62,33
D(5) 62,33
C(8) 216,200
Query Planning Example #3
Id T Pre Type Cost Paths of length 2:
0 A - index on A.a1 0, 56, 33
1 A B primary-key 0, 45, -1 Path Cost
2 B - index on B.a3 0, 62, 33 A(0) B(4)
A(0), 33
96, 65
3 B D primary-key 0, 45, -1 A(0),
B(2) D(5) 96, 66
33
4 B A index on B.a_id 0, 62, 32
A(0),
D(5) C(8) 249, 233
33
5 D - index on D.a2 0, 62, 33
6 D B index on D.b_id 0, 62, 33 ...
C(8) ...
216
7 D C index on D.c_id 0, 62, 33
8 C - full-table scan 0, 216, 200
9 C D primary-key 0, 45, 0
Paths of length 1:
Path Cost
A(0) 56,33
B(2) 62,33
D(5) 62,33
C(8) 216,200
Query Planning Example #3
Id T Pre Type Cost Paths of length 2:
0 A - index on A.a1 0, 56, 33
1 A B primary-key 0, 45, -1 Path Cost
2 B - index on B.a3 0, 62, 33 A(0) B(4)
A(0), 33
96, 65
3 B D primary-key 0, 45, -1 A(0),
B(2) D(5) 96, 66
33
4 B A index on B.a_id 0, 62, 32
A(0),
D(5) C(8) 249, 233
33
5 D - index on D.a2 0, 62, 33
6 D B index on D.b_id 0, 62, 33 B(2),
C(8) A(0) 91, 66
216
7 D C index on D.c_id 0, 62, 33 B(2), A(1) 82, 32
8 C - full-table scan 0, 216, 200
B(2), D(5) 96, 66
9 C D primary-key 0, 45, 0
B(2), D(6) 96, 65
Paths of length 1:
B(2), C(8) 249, 233
Path Cost
... ...
A(0) 56,33
B(2) 62,33
D(5) 62,33
C(8) 216,200
Query Planning Example #3
Id T Pre Type Cost Paths of length 2:
0 A - index on A.a1 0, 56, 33
1 A B primary-key 0, 45, -1 Path Cost
2 B - index on B.a3 0, 62, 33 A(0) B(4)
A(0), 33
96, 65 X
3 B D primary-key 0, 45, -1 A(0),
B(2) D(5) 96, 66
33
4 B A index on B.a_id 0, 62, 32
A(0),
D(5) C(8) 249, 233
33
5 D - index on D.a2 0, 62, 33
6 D B index on D.b_id 0, 62, 33 B(2),
C(8) A(0) 91, 66
216 X
7 D C index on D.c_id 0, 62, 33 B(2), A(1) 82, 32
8 C - full-table scan 0, 216, 200
B(2), D(5) 96, 66 X
9 C D primary-key 0, 45, 0
B(2), D(6) 96, 65
Paths of length 1:
B(2), C(8) 249, 233
Path Cost
... ...
A(0) 56,33
B(2) 62,33
D(5) 62,33
C(8) 216,200
Query Planning Example #3
Id T Pre Type Cost Paths of length 2:
0 A - index on A.a1 0, 56, 33
1 A B primary-key 0, 45, -1 Path Cost
2 B - index on B.a3 0, 62, 33 A(0) D(5)
A(0), 33
96, 66
3 B D primary-key 0, 45, -1 A(0),
B(2) C(8) 249, 233
33
4 B A index on B.a_id 0, 62, 32
B(2),
D(5) A(1) 82, 32
33
5 D - index on D.a2 0, 62, 33
6 D B index on D.b_id 0, 62, 33 C(8) D(6)
B(2), 216
96, 65
7 D C index on D.c_id 0, 62, 33 B(2), C(8) 249, 233
8 C - full-table scan 0, 216, 200
... ...
9 C D primary-key 0, 45, 0
Paths of length 1:
Path Cost
A(0) 56,33
B(2) 62,33
D(5) 62,33
C(8) 216,200
Query Planning Example #3
Id T Pre Type Cost Paths of length 2:
0 A - index on A.a1 0, 56, 33
1 A B primary-key 0, 45, -1 Path Cost
2 B - index on B.a3 0, 62, 33 A(0) D(5)
A(0), 33
96, 66
3 B D primary-key 0, 45, -1 A(0),
B(2) C(8) 249, 233
33
4 B A index on B.a_id 0, 62, 32
B(2),
D(5) A(1) 82, 32
33
5 D - index on D.a2 0, 62, 33
6 D B index on D.b_id 0, 62, 33 C(8) D(6)
B(2), 216
96, 65
7 D C index on D.c_id 0, 62, 33 B(2), C(8) 249, 233
8 C - full-table scan 0, 216, 200
D(5), A(0) 91, 66
9 C D primary-key 0, 45, 0
D(5), B(2) 96, 66
Paths of length 1:
D(5), B(3) 82, 32
Path Cost
D(5), C(8) 249, 233
A(0) 56,33
D(5), C(9) 144, 66
B(2) 62,33
... ...
D(5) 62,33
C(8) 216,200
Query Planning Example #3
Id T Pre Type Cost Paths of length 2:
0 A - index on A.a1 0, 56, 33
1 A B primary-key 0, 45, -1 Path Cost
2 B - index on B.a3 0, 62, 33 A(0) D(5)
A(0), 33
96, 66 X
3 B D primary-key 0, 45, -1 A(0),
B(2) C(8) 249, 233
33
4 B A index on B.a_id 0, 62, 32
B(2),
D(5) A(1) 82, 32
33
5 D - index on D.a2 0, 62, 33
6 D B index on D.b_id 0, 62, 33 C(8) D(6)
B(2), 216
96, 65 X
7 D C index on D.c_id 0, 62, 33 B(2), C(8) 249, 233
8 C - full-table scan 0, 216, 200
D(5), A(0) 91, 66
9 C D primary-key 0, 45, 0
D(5), B(2) 96, 66 X
Paths of length 1:
D(5), B(3) 82, 32
Path Cost
D(5), C(8) 249, 233 X
A(0) 56,33
D(5), C(9) 144, 66
B(2) 62,33
... ...
D(5) 62,33
C(8) 216,200
Query Planning Example #3
Id T Pre Type Cost Paths of length 2:
0 A - index on A.a1 0, 56, 33
1 A B primary-key 0, 45, -1 Path Cost
2 B - index on B.a3 0, 62, 33 A(0) C(8)
A(0), 33
249, 233
3 B D primary-key 0, 45, -1 B(2),
B(2) A(1) 82, 32
33
4 B A index on B.a_id 0, 62, 32
D(5) C(8)
B(2), 33
249, 233
5 D - index on D.a2 0, 62, 33
6 D B index on D.b_id 0, 62, 33 C(8)
D(5), A(0) 216
91, 66
7 D C index on D.c_id 0, 62, 33 D(5), B(3) 82, 32
8 C - full-table scan 0, 216, 200
9 C D primary-key 0, 45, 0
D(5), C(9) 144, 66
Path Cost
A(0) 56,33
B(2) 62,33
D(5) 62,33
C(8) 216,200
Query Planning Example #3
Id T Pre Type Cost Paths of length 2:
0 A - index on A.a1 0, 56, 33
1 A B primary-key 0, 45, -1 Path Cost
2 B - index on B.a3 0, 62, 33 A(0) C(8)
A(0), 33
249, 233
3 B D primary-key 0, 45, -1 B(2),
B(2) A(1) 82, 32
33
4 B A index on B.a_id 0, 62, 32
D(5) C(8)
B(2), 33
249, 233
5 D - index on D.a2 0, 62, 33
6 D B index on D.b_id 0, 62, 33 C(8)
D(5), A(0) 216
91, 66
7 D C index on D.c_id 0, 62, 33 D(5), B(3) 82, 32
8 C - full-table scan 0, 216, 200
9 C D primary-key 0, 45, 0
D(5), C(9) 144, 66
Path Cost
A(0) 56,33
B(2) 62,33
D(5) 62,33
C(8) 216,200
Query Planning Example #3
Id T Pre Type Cost Paths of length 2:
0 A - index on A.a1 0, 56, 33
1 A B primary-key 0, 45, -1 Path Cost
2 B - index on B.a3 0, 62, 33 A(0) C(8)
A(0), 33
249, 233
3 B D primary-key 0, 45, -1 B(2),
B(2) A(1) 82, 32
33
4 B A index on B.a_id 0, 62, 32
D(5) C(8)
B(2), 33
249, 233
5 D - index on D.a2 0, 62, 33
6 D B index on D.b_id 0, 62, 33 C(8)
D(5), A(0) 216
91, 66
7 D C index on D.c_id 0, 62, 33 D(5), B(3) 82, 32
8 C - full-table scan 0, 216, 200
9 C D primary-key 0, 45, 0
D(5), C(9) 144, 66
Best query plan: P(0), L(7), S(2), O(10), C(13), N1(17), R(21), N2(18) Cost: 176
max=9 plan: R(20), P(0), L(7), O(10), C(13), N1(17), S(2), N2(18) Cost: 179
Summary: How SQLite Works
●
In-process library. No server. Parser
●
One-file database
Code Generator
●
Power-safe transactions
Virtual Machine
●
Row-store
●
Everything's a b-tree B-Tree
●
Schema stored as a table of Pager
CREATE statements
OS Interface
●
Bytecode
●
Queries planned by solving TSP
Website: https://sqlite.org/
Sources: https://sqlite.org/src/timeline
Forum: https://sqlite.org/forum