我从源代码构建了sqlite3以包含FTS3支持,然后在包含150万行数据的现有sqlite数据库中创建了一个新表,使用
CREATE VIRTUAL TABLE data USING FTS3(codes text);
然后使用
INSERT INTO data(codes) SELECT originalcodes FROM original_data;
然后用
查询每个表SELECT * FROM original_data WHERE originalcodes='RH12';
由于我在该列上有索引
,因此立即返回FTS3表上的查询
SELECT * FROM data WHERE codes='RH12';
花了差不多28秒
有人可以帮助解释我做错了什么,因为我预计这会更快“
答案 0 :(得分:2)
documentation解释说:
可以使用两种不同形式的SELECT语句有效查询FTS表:
- 按rowid查询。如果SELECT语句的WHERE子句包含“rowid =?”形式的子句,在哪里?是一个SQL表达式,FTS能够使用等效的SQLite INTEGER PRIMARY KEY索引直接检索请求的行。
- 全文查询。如果SELECT语句的WHERE子句包含“MATCH?”形式的子句,则FTS能够使用内置全文索引将搜索限制为与指定的全文查询字符串匹配的文档作为MATCH条款的右手操作数。
如果这两种查询策略都不能使用,那么FTS表上的所有查询都是使用整个表的线性扫描来实现的。
要进行有效的查询,您应该使用
SELECT * FROM data WHERE codes MATCH 'RH12'
但是这会找到包含搜索字符串的所有记录。
要有效地执行“正常”查询,您必须在普通表中保留数据的副本。 (如果要节省空间,可以使用contentless or external content表。)
答案 1 :(得分:0)
您应该仔细阅读documentation。
使用WHERE col = 'value'
对虚拟FTS表的任何查询都会很慢(查询ROWID
除外),但使用WHERE col MATCH 'value'
的查询将使用FTS并且速度很快。
答案 2 :(得分:0)
我不是这方面的专家,但这里有几点需要考虑。 你的测试有缺陷(我认为)。你对比了一个场景,你有一个精确的文本匹配(索引可以在original_data上使用 - 没有什么会超过这个场景)与fts3表上的相等(我不确定FTS3甚至可以发挥作用)这种类型的查询)。如果你想比较苹果和苹果(看看FTS3的好处),你会想要将original_data上的“喜欢”操作与数据上的FTS3“匹配”操作进行比较。