SQLITE FTS3查询比标准选项卡慢

SQLITE FTS3查询比标准选项卡慢,sql,sqlite,fts3,Sql,Sqlite,Fts3,我从源代码构建sqlite3以包含FTS3支持,然后在现有sqlite数据库中创建一个新表,其中包含150万行数据,使用 CREATE VIRTUAL TABLE data USING FTS3(codes text); 然后使用 INSERT INTO data(codes) SELECT originalcodes FROM original_data; 然后用 SELECT * FROM original_data WHERE originalcodes='RH12'; 这会立即返回

我从源代码构建sqlite3以包含FTS3支持,然后在现有sqlite数据库中创建一个新表,其中包含150万行数据,使用

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秒

有人能帮我解释一下我做错了什么,因为我希望这会快得多

你应该仔细阅读

使用
其中col='value'
对虚拟FTS表的任何查询都会很慢(对
ROWID
的查询除外),但使用
其中col匹配'value'
的查询将使用FTS和fast。

您应该仔细阅读


使用
其中col='value'
对虚拟FTS表的任何查询都会很慢(除了对
ROWID
的查询),但使用
其中col匹配'value'
的查询将使用FTS和fast。

我不是这方面的专家,但这里有一些事情需要考虑。
(我认为)你的测试有缺陷。您将有一个精确文本匹配的场景(索引可以用于原始_数据-没有什么比这个场景更好)与fts3表上的相等(我不确定fts3是否会在这种类型的查询中发挥作用)进行对比。如果你想对苹果进行比较(看看FTS3的好处),你需要将原始数据上的“相似”操作与FTS3数据上的“匹配”操作进行比较。

我不是这方面的专家,但这里有一些事情需要考虑。 (我认为)你的测试有缺陷。您将有一个精确文本匹配的场景(索引可以用于原始_数据-没有什么比这个场景更好)与fts3表上的相等(我不确定fts3是否会在这种类型的查询中发挥作用)进行对比。如果您想对苹果进行比较(查看FTS3的优点),您需要将原始数据上的“相似”操作与数据上的FTS3“匹配”操作进行比较。

说明:

可以使用两种不同形式的SELECT语句高效地查询FTS表:

  • 按rowid查询。如果SELECT语句的WHERE子句包含形式为“rowid=?”的子子句,则WHERE?是一个SQL表达式,FTS可以使用与SQLite INTEGER主键索引等效的方法直接检索请求的行
  • 全文查询。如果SELECT语句的WHERE子句包含格式为“MATCH?”的子子句,FTS可以使用内置全文索引将搜索限制为与指定为MATCH子句右操作数的全文查询字符串匹配的文档
如果这两种查询策略都不能使用,则FTS表上的所有查询都将使用整个表的线性扫描来实现

为了实现高效查询,您应该使用

SELECT * FROM data WHERE codes MATCH 'RH12'
但这将查找包含搜索字符串的所有记录

要高效地执行“普通”查询,必须在普通表中保留数据的副本。 (如果您想节省空间,可以使用表格。)

说明:

可以使用两种不同形式的SELECT语句高效地查询FTS表:

  • 按rowid查询。如果SELECT语句的WHERE子句包含形式为“rowid=?”的子子句,则WHERE?是一个SQL表达式,FTS可以使用与SQLite INTEGER主键索引等效的方法直接检索请求的行
  • 全文查询。如果SELECT语句的WHERE子句包含格式为“MATCH?”的子子句,FTS可以使用内置全文索引将搜索限制为与指定为MATCH子句右操作数的全文查询字符串匹配的文档
如果这两种查询策略都不能使用,则FTS表上的所有查询都将使用整个表的线性扫描来实现

为了实现高效查询,您应该使用

SELECT * FROM data WHERE codes MATCH 'RH12'
但这将查找包含搜索字符串的所有记录

要高效地执行“普通”查询,必须在普通表中保留数据的副本。 (如果要节省空间,可以使用表格。)