SQLite:应该像';searchstr%&x27;使用索引?

SQLite:应该像';searchstr%&x27;使用索引?,sql,sqlite,cocoa,sql-like,query-performance,Sql,Sqlite,Cocoa,Sql Like,Query Performance,我有一个有几个字段的数据库 word_id — INTEGER PRIMARY_KEY word — TEXT ... ..和~15万行 因为这是一本词典,所以我正在使用LIKE搜索一个带掩码的单词。 它过去工作得很好,需要15毫秒才能找到匹配的行。该表有一个字段'word'的索引。 最近我修改了表(该表的一些字段超出了范围),发生了一些事情——执行查询需要400毫秒,所以我理解这一点,因为它现在无法使用索引。 使用=而不是like的直接查询显示10ms结果。 有人知道这里发生了什么吗?在这种

我有一个有几个字段的数据库

word_id — INTEGER PRIMARY_KEY
word — TEXT
...
..和~15万行

因为这是一本词典,所以我正在使用LIKE搜索一个带掩码的单词。 它过去工作得很好,需要15毫秒才能找到匹配的行。该表有一个字段
'word'
的索引。 最近我修改了表(该表的一些字段超出了范围),发生了一些事情——执行查询需要400毫秒,所以我理解这一点,因为它现在无法使用索引。 使用=而不是like的直接查询显示10ms结果。
有人知道这里发生了什么吗?

在这种情况下,索引不能安全使用。一个简单的实现将改变这一点:

。。。其中有“搜索字符串%”之类的词。

进入

。。。其中word>='search\u string'和word<'search\u strinh'

通过增加搜索字符串的最后一个字符。大于和小于运算符可以使用索引,而LIKE不能

不幸的是,这在一般情况下是行不通的。
LIKE
运算符不区分大小写,这意味着
'a'LIKE'a'
为true。上述转换将用大写字母打断任何搜索字符串

但是,在某些情况下,您知道区分大小写与特定列无关,并且上面的转换是安全的。在这种情况下,您有两种选择

  • 对覆盖此特定字段的索引使用
    NOCASE
    排序序列
  • 通过运行PRAGMA case\u sensitive\u LIKE=ON,在整个操作员程序范围内更改
    LIKE
    的行为
  • 这些行为中的任何一种都将使SQLite能够透明地为您执行上述转换;您只需像往常一样继续使用
    ,SQLite将重写底层查询以使用索引


    你可以在上阅读更多关于“类似优化”的内容。

    我想是的,你可能想看看b-树,因为b-树在范围查询和类似比较方面很有效。嗯,索引不假设创建b-树吗?你的意思是,我应该自己创建一个b-树?百分比是否总是只在搜索词的末尾,而不是开始?也许可以尝试删除并重新创建索引?你应该尝试使用
    EXPLAIN QUERY PLAN
    来查看你的查询发生了什么。该死!在上面的线程中,我提到了我在上次创建索引(有效)时使用了一些参数。所以,这是
    collatenocase
    。我花了6个小时都没找到答案。不错的链接,我也读过,但它似乎只是从我的注意力中溜走了。谢谢你,荷马!你刚才救了我多少时间,天知道。我想你是说
    PRAGMA case\u sensitive\u like=ONLike
    默认情况下不区分大小写。在您链接到的文章中:“如果使用内置的二进制排序序列对运算符左侧命名的列进行索引,并且启用了区分大小写的类,则可能会发生类似的优化。”啊,没错。我会修好的。谢谢