如何提高sqlite之类的语句性能

eri*_*ang 9 sql sqlite performance sql-like

我创建一个表使用这样的模式:

CREATE TABLE wordIndex(id integer primary key, word varchar(128), offset integer, length integer);
CREATE INDEX word_idx on wordIndex(word);
Run Code Online (Sandbox Code Playgroud)

现在该表有大约450,000行记录.当我在ipod4上使用Like语句时,性能不佳:从wordIndex中选择*,其中的单词如'test acces%'; 使用说明输出:

explain select * from wordIndex where word like 'test acces%';
0|Trace|0|0|0||00|
1|Goto|0|16|0||00|
2|OpenRead|0|2|0|4|00|
3|Rewind|0|14|0||00|
4|String8|0|2|0|test acces%|00|
5|Column|0|1|3||00|
6|Function|1|2|1|like(2)|02|
7|IfNot|1|13|1||00|
8|Rowid|0|4|0||00|
9|Column|0|1|5||00|
10|Column|0|2|6||00|
11|Column|0|3|7||00|
12|ResultRow|4|4|0||00|
13|Next|0|4|0||01|
14|Close|0|0|0||00|
15|Halt|0|0|0||00|
16|Transaction|0|0|0||00|
17|VerifyCookie|0|2|0||00|
18|TableLock|0|2|0|wordIndex|00|
19|Goto|0|2|0||00|
Run Code Online (Sandbox Code Playgroud)

可能是我需要构建一个额外的倒排索引以改善性能或......?谢谢提前!

Gor*_*off 13

索引并且like在大多数数据库中都不相处.最好的办法是尽可能将查询重写为范围查询,因为将使用索引:

select *
from wordIndex
where word between 'test acces' and 'test acces{'
Run Code Online (Sandbox Code Playgroud)

(开括号是紧跟在'z'之后的ASCII字符.)

如果您在单词的开头寻找模式(比如'%test'),那么您可能不得不让自己辞去全表扫描.

编辑:

like当模式以常量开始时,索引和*do`现在在大多数数据库中相处,所以你可以这样做:

select *
from wordIndex
where word like 'test acces%' ;
Run Code Online (Sandbox Code Playgroud)

但是,我不是100%肯定SQLite,所以检查执行计划以查看它是否使用索引.

  • 谢谢 Gordon Lionff,它确实有效。查询重写之前:执行时间:1.756531 秒,查询重写之后:执行时间:在我的 iPod Touch 4 上为 0.011285。 (2认同)

Ham*_*yan 5

试试这个:

SELECT * FROM wordIndex
WHERE word COLLATE NOCASE BETWEEN @SearchString AND @SearchString || '~~~~~~~~~~'
Run Code Online (Sandbox Code Playgroud)

"〜"是最大的ASCII符号.