sqlite not using index with like query

前端 未结 4 1902
别那么骄傲
别那么骄傲 2021-02-19 10:27

Ive been trying to get sqlite to use an index with a like to no avail. Ive tried collate nocase and still no luck. Anyone have any ideas on how to get sqlite to do a like hittin

相关标签:
4条回答
  • 2021-02-19 10:59

    In SQLite 3.6.23.1, the index on test is used:

    > explain query plan select * from test where name like 'test%';
    TABLE test WITH INDEX idx_test_name
    
    > explain query plan select * from test2 where name like 'test%';
    TABLE test2
    
    > explain query plan select * from test3 where name like 'test%';
    TABLE test3
    

    With a development version of SQLite 3.7.15, both test's and test3's indexes are used (the index on test2 is used for scanning, not searching):

    > explain query plan select * from test where name like 'test%';
    SEARCH TABLE test USING COVERING INDEX idx_test_name (name>? AND name<?) (~31250 rows)
    
    > explain query plan select * from test2 where name like 'test%';
    SCAN TABLE test2 USING COVERING INDEX idx_test2_name (~500000 rows)
    
    > explain query plan select * from test3 where name like 'test%';
    SEARCH TABLE test3 USING COVERING INDEX idx_test3_name (name>? AND name<?) (~31250 rows)
    

    So the answer is to update SQLite.

    0 讨论(0)
  • 2021-02-19 11:03

    Quote from sqlite mail list (http://www.mail-archive.com/sqlite-users@sqlite.org/msg27760.html)

    LIKE is case-insensitive by default. To have it use your index, you need to either make the index case-insensitive:

    CREATE INDEX test_name ON test (name COLLATE NOCASE);

    or make LIKE case-sensitive:

    PRAGMA case_sensitive_like = 1;

    0 讨论(0)
  • 2021-02-19 11:05

    From the docs:

    Terms that are composed of the LIKE or GLOB operator can sometimes be used to constrain indices. There are many conditions on this use:

    • The left-hand side of the LIKE or GLOB operator must be the name of an indexed column with TEXT affinity.
    • The right-hand side of the LIKE or GLOB must be either a string literal or a parameter bound to a string literal that does not begin with a wildcard character.
    • The ESCAPE clause cannot appear on the LIKE operator.
    • The built-in functions used to implement LIKE and GLOB must not have been overloaded using the sqlite3_create_function() API.
    • For the GLOB operator, the column must be indexed using the built-in BINARY collating sequence.
    • For the LIKE operator, if case_sensitive_like mode is enabled then the column must indexed using BINARY collating sequence, or if case_sensitive_like mode is disabled then the column must indexed using built-in NOCASE collating sequence.
    0 讨论(0)
  • 2021-02-19 11:05

    I also have the same issue with org.xerial/sqlite-jdbc "3.25.2". A simple TEXT based index is not getting used with LIKE operator. But, if I put =, the index gets used. My table schema :

     create table if not exists test (ID INTEGER PRIMARY KEY, VALUE TEXT NOT NULL)
     create index test_idx on test(value)
     insert into test (ID,  VALUE) values (1, 'gold bangles')
     insert into test (ID,  VALUE) values (2, 'gold bandana')
     insert into test (ID,  VALUE) values (2, 'gold bracelet')
    
     explain query plan select * from test where value='gold bandana'
    
     Output:
     0|0|0|SEARCH TABLE test USING COVERING INDEX test_idx(VALUE=?)
    
     explain query plan select * from test where value like 'gold%'
    
     Output:
     0|0|0|SCAN TABLE test
    
    0 讨论(0)
提交回复
热议问题