【问题标题】:SQLite speed up select with collate nocaseSQLite 使用 collat​​e nocase 加速选择
【发布时间】:2017-12-10 08:56:59
【问题描述】:

我有 SQLite 数据库:

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。我想加快速度。我试图添加索引,但它没有帮助(可能是我做错了什么?)。如何以大约等于第一个查询的速度执行第二个查询?

【问题讨论】:

    标签: sql sqlite select


    【解决方案1】:

    只有使用与查询相同的排序规则时,才能使用索引来加快搜索速度。

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

    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。)

    【讨论】:

    • 第一个查询没有 COLLATE,所以当表定义对要匹配的列有 COLLATE NOCASE 时,匹配是隐式不区分大小写的,这应该是第一个查询更快。我是否遗漏了什么,因为您说这会使第一个查询变慢?
    • @Siddu 第一个查询旨在使用区分大小写的排序规则,因此要正确运行,需要将其更改为使用 COLLATE BINARY。
    • @CL。感谢您提供的超级有用的答案!所以,要明确一点:如果整个表不区分大小写并且在所有列上都有 collat​​e nocase,那么索引是否也需要显式 collat​​e nocase 或者列定义就足够了?
    • @AlexWeber 查看答案中第二句的开头,或documentation
    猜你喜欢
    • 2013-02-03
    • 2012-06-27
    • 1970-01-01
    • 1970-01-01
    • 2018-02-25
    • 1970-01-01
    • 2011-07-18
    • 2020-09-27
    • 1970-01-01
    相关资源
    最近更新 更多