SQLite 简介 | About SQLite | Architecture of SQLite | SQLite Bytecode Engine | How To Compile SQLite

poetry.csv:

author,title,text

王维,送别,下马饮君酒,问君何所之。君言不得意,归卧南山陲。但去莫复闻,白云无尽时。

韦应物,寄全椒山中道士,今朝郡斋冷,忽念山中客。涧底束荆薪,归来煮白石。欲持一瓢酒,远慰风雨夕。落叶满空山,何处寻行迹。

韦应物,长安遇冯著,客从东方来,衣上灞陵雨。问客何为来,采山因买斧。冥冥花正开,扬扬燕新乳。昨别今已春,鬓丝生几缕。

王昌龄,塞上曲,蝉鸣空桑林,八月萧关道。出塞复入塞,处处黄芦草。从来幽并客,皆向沙场老。莫学游侠儿,矜夸紫骝好。

李白,子夜四时歌:春歌,秦地罗敷女,采桑绿水边。素手青条上,红妆白日鲜。蚕饥妾欲去,五马莫留连。

孟郊,游子吟,慈母手中线,游子身上衣。临行密密缝,意恐迟迟归。谁言寸草心,报得三春辉?

陈子昂,登幽州台歌,前不见古人,后不见来者。念天地之悠悠,独怆然而涕下!

create-db.sh和create-db-idx.sh: [create-db.sh里没有CREATE INDEX一句]

sqlite3 <<-"END"

.open t.db

DROP TABLE IF EXISTS poetry ;

.import --csv poetry.csv poetry

.schema poetry

CREATE INDEX idx ON poetry(author, title, text) ;

.quit

END

eq.sh和like.sh:

sqlite3 <<-"END"

.open t.db

EXPLAIN SELECT * from poetry WHERE author='韦应物';

SELECT * from poetry WHERE author='韦应物';

.quit

END

sqlite3 <<-"END"

.open t.db

EXPLAIN SELECT * from poetry WHERE author LIKE '韦%';

SELECT * from poetry WHERE author LIKE '韦%';

.quit

END

修改程序,sqlite3VdbeExec的switch (90578行左右)前加行printf("pOp->opcode=%d\n", pOp->opcode);

$ create-db-idx.sh

$ eq.sh | wc -l

63

$ like.sh | wc -l

90

$ grep -n OP_SeekGE sqlite3.c | grep 23

15965:#define OP_SeekGE 23 /* jump, synopsis: key=r[P3@P4] */

$ grep -n OP_Next sqlite3.c | grep 39

15981:#define OP_Next 39 /* jump */

$ like.sh | grep 39 | wc -l

10

在.csv里增加2行(从7到9),再来一遍:

$ like.sh | grep opcode=39 | wc -l

12

$ like.sh | grep opcode=23 | wc -l

0

$ eq.sh | grep opcode=23 | wc -l

1

简单分析/猜测:

rewind是(磁带)倒带,像fseek(db_file, 0, SEEK_SET);

SeekGE: Seek If Greater Than,像我们在C++程序里用二分法在有序数组里找,找到后往左右两边扩展下;或者用multiset. 数据库用的是B-Tree.

like,sqlite也没有好办法,似乎类似于for循环里逐一调用函数like. 换一个表,max, min, total类似。

MySQL Like模糊查询速度太慢如何解决 | 解决SQL加上like模糊查询以后变得特别慢 恐怕没有从根本上解决问题。好比是个m*n的循环,n变n-1后,当m很大如1亿时,总时间还是不短。但数据库不是花1小时查出所有符合条件的记录(如100万条)一下子返回给客户端,而是如0.01ms后开始逐条返回(有点像Python的生成器),所以没感觉慢。

SQLite Indexed By - 菜鸟教程: "INDEXED BY index-name" 子句规定必须需要命名的索引来查找前面表中值。如果索引名 index-name 不存在或不能用于查询,然后 SQLite 语句的准备失败。

sqlite3好像还支持全文检索和正则表达式。查author='韦应物' and text里有'雨'或有'鬓‘呢?multiset都很少用的我,过去和现在都不明白这咋建索引。

Information retrieval - Detailed Pedia

sqlite3.c 源码24万行; Tiny C Compiler 4万多行; minix 1万多行(kernel 5000多行),几千万行的应该是把各种驱动程序,用户界面,Explorer, WordPad等全算上了。

sqlite3VdbeExec()从90418行到98513行,8000多行。sqlite里的assert有6926行。gdb里b sqlite3VdbeExec

-g编译出来的sqlite3 2.7MB; ffmpeg几十MB,各种编解码器多如牛毛,程序里好像并没有多少表格如char tbl[] = { 1, 2, 3, ... };

How MySQL Uses Indexes

Our Indexes - clustered and non clustered - Firebolt

查看原文