我有一个包含多个字段的数据库:
word_id — INTEGER PRIMARY_KEY
word — TEXT
...
还有大约 15 万行。由于这是一本字典,因此我正在使用
'search_string%'
搜索带有掩码 LIKE
的单词。它曾经有效,需要 15 毫秒才能找到匹配的行。该表有一个字段索引 'word'
。
我修改了表(一些字段超出了范围),执行查询需要 400 毫秒,所以我明白了,因为它现在无法使用索引。使用
=
而不是 LIKE
进行直接查询会显示 10 毫秒结果。这里发生了什么事?
在这种情况下不能安全地使用索引。一个简单的实现将改变这一点:
... WHERE word LIKE 'search_string%'
进入
... WHERE word >= 'search_string' AND word < 'search_strinh'
通过增加搜索字符串的最后一个字符。大于和小于运算符可以使用索引,而 LIKE 则不能。
不幸的是,这在一般情况下不起作用。
LIKE
运算符不区分大小写,这意味着 'a' LIKE 'A'
为 true。上述转换将破坏任何带有大写字母的搜索字符串。
然而,在某些情况下,您“知道”区分大小写与特定列无关,并且上述转换是安全的。在这种情况下,您有两个选择。在覆盖此特定字段的索引上使用
NOCASE
通过运行
LIKE
PRAGMA case_sensitive_like = ON;
运算符的行为
这些行为中的任何一个都将使 SQLite 透明地为您完成上述转换;您只需像往常一样继续使用
LIKE
您可以在SQLite 查询优化器概述页面阅读有关“LIKE 优化”的更多信息。
GLOB prefix*
解决方法
此方法确实使用索引,因此对于LIKE prefix%
来说这是一个很好的解决方法,不需要修改表排序规则:
SELECT * FROM mytable WHERE mycolumn GLOB 'myprefix*'
来自文档:
GLOB
运算符与
LIKE
类似,但其通配符使用 Unix 文件通配符语法。此外,与GLOB
不同,LIKE
区分大小写。另请参阅:文本列上的索引可以加速基于前缀的 LIKE 查询吗?
在 Sqlite 3.40.1、Ubuntu 23.04 的大型数据库的TEXT