SQLite 使用 autoindex 而不是我自己的索引

Chr*_*tro 3 sql sqlite indexing pysqlite

我在 UNIQUE 表中遇到 SQLite 自动索引问题。我创建了如下表。

c.execute('''CREATE TABLE user(
    id INTEGER PRIMARY KEY,
    email TEXT NOT NULL UNIQUE,
    password TEXT NOT NULL,
    name TEXT NOT NULL,
    );'''
)
c.execute('CREATE INDEX USR on user(email, password);')
Run Code Online (Sandbox Code Playgroud)

但是当我使用解释查询计划检查时,SQLite使用它自己提供的自动索引。如何避免使用我自己的索引而不是自动索引?我如何尝试:

c.execute('EXPLAIN QUERY PLAN SELECT id, name FROM social WHERE email = "a@a.com" AND password = 'password'')
Run Code Online (Sandbox Code Playgroud)

结果是:

(0, 0, 0, 'SEARCH TABLE social USING INDEX sqlite_autoindex_user_1(email=?))
Run Code Online (Sandbox Code Playgroud)

Mik*_*ll' 5

在你的例子中,我认为“sqlite_autoindex_user_1”是 SQLite 用于实现“email”上声明的约束的索引。尽管有这个名称,但它是一个内部索引,而不是自动索引。

不要将自动索引与内部索引(名称如“sqlite_autoindex_table_N”)混淆,内部索引有时是为了实现 PRIMARY KEY 约束或 UNIQUE 约束而创建的。此处描述的自动索引仅在单个查询期间存在,永远不会保留到磁盘,并且仅对单个数据库连接可见。内部索引是 PRIMARY KEY 和 UNIQUE 约束实现的一部分,是持久的并保存到磁盘,并且对所有数据库连接都可见。由于遗留原因,术语“自动索引”出现在内部索引的名称中,并不表示内部索引和自动索引相关。

来源

查询优化器认为使用“电子邮件”上的索引速度最快。这可能是对的。


要了解 SQLite 如何使用覆盖索引“medp”,请构建一个如下所示的测试表。

create table social_test (
  id integer primary key, 
  name text not null,    -- no UNIQUE constraint for testing
  tampil integer not null
);

create index medp on social (name, tampil);
Run Code Online (Sandbox Code Playgroud)

如果需要,可以插入一百万行。

analyze social;
explain query plan select * from social where name = 'facebook' and tampil = 6;
0|0|0|SEARCH TABLE social USING COVERING INDEX medp (name=? AND tampil=?)
Run Code Online (Sandbox Code Playgroud)