SQLite加速选择collat​​e nocase

bur*_*huy 3 sql sqlite select

我有SQLite db:

CREATE TABLE IF NOT EXISTS Commits
(
    GlobalVer INTEGER PRIMARY KEY,
    Data blob NOT NULL
) WITHOUT ROWID;
CREATE TABLE IF NOT EXISTS Streams
(
    Name char(40) NOT NULL,
    GlobalVer INTEGER NOT NULL,
    PRIMARY KEY(Name, GlobalVer)
) WITHOUT ROWID;
Run Code Online (Sandbox Code Playgroud)

我想做1选:

SELECT Commits.Data
  FROM Streams JOIN Commits ON Streams.GlobalVer=Commits.GlobalVer
 WHERE 
    Streams.Name = ?
ORDER BY Streams.GlobalVer
LIMIT ? OFFSET ?
Run Code Online (Sandbox Code Playgroud)

之后,我想做另一个选择:

SELECT Commits.Data,Streams.Name
  FROM Streams JOIN Commits ON Streams.GlobalVer=Commits.GlobalVer
 WHERE 
    Streams.Name = ? COLLATE NOCASE
ORDER BY Streams.GlobalVer
LIMIT ? OFFSET ?
Run Code Online (Sandbox Code Playgroud)

问题是第二选择工作超慢.我想这是因为COLLATE NOCASE.我想加快它.我试图添加索引,但它没有帮助(可能是我做了一些错误?).如何以大约等于第一个查询的速度执行第二个查询?

CL.*_*CL. 7

仅当索引使用与查询相同的排序规则时,索引才可用于加速搜索.

默认情况下,索引从表列中获取排序规则,因此您可以更改表定义:

CREATE TABLE IF NOT EXISTS Streams
(
    Name      char(40) NOT NULL COLLATE NOCASE,
    GlobalVer INTEGER  NOT NULL,
    PRIMARY KEY(Name, GlobalVer)
) WITHOUT ROWID;
Run Code Online (Sandbox Code Playgroud)

但是,这会使第一个查询变慢.

要加速两个查询,您需要两个索引,每个索引一个.因此,对隐式索引使用默认排序规则,对显式索引使用NOCASE:

CREATE TABLE IF NOT EXISTS Streams
(
    Name      char(40) NOT NULL COLLATE NOCASE,
    GlobalVer INTEGER  NOT NULL,
    PRIMARY KEY(Name, GlobalVer)
) WITHOUT ROWID;
CREATE INDEX IF NOT EXISTS Streams_nocase_idx ON Streams(Name COLLATE NOCASE, GlobalVar);
Run Code Online (Sandbox Code Playgroud)

(将第二列添加到索引会加快此查询中的ORDER BY.)