我有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;
我想做1选:
SELECT Commits.Data
FROM Streams JOIN Commits ON Streams.GlobalVer=Commits.GlobalVer
WHERE
Streams.Name = ?
ORDER BY Streams.GlobalVer
LIMIT ? OFFSET ?
之后我想再做一次选择:
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 ?
问题是第二选择工作超慢。我认为这是因为COLLATE NOCASE
。我想加快它。我试图添加索引,但它没有帮助(可能是我做错了吗?)。如何以大约等于第一个查询的速度执行第二次查询?
答案 0 :(得分:6)
只有当索引使用与查询相同的排序规则时,才能使用索引来加速搜索。
默认情况下,索引从表列中获取排序规则,因此您可以更改表定义:
CREATE TABLE IF NOT EXISTS Streams
(
Name char(40) NOT NULL COLLATE NOCASE,
GlobalVer INTEGER NOT NULL,
PRIMARY KEY(Name, GlobalVer)
) WITHOUT ROWID;
但是,这会使第一个查询变慢。
要加速两个查询,您需要两个索引,每个索引一个。因此,对隐式索引使用默认排序规则,对显式索引使用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);
(将第二列添加到索引会加快此查询中的ORDER BY。)