1

我到处都解释说我应该在这样的情况下创建一个表索引:

SELECT * FROM foo, bar WHERE foo.field1 < <some_value>;

不过我的情况不一样。

我正在使用 SQLite 并具有以下架构:

CREATE TABLE leagues(
    id integer primary key,
    ...
);
CREATE TABLE players(
    playerid integer, 
    id integer, 
    type integer, 
    value double, 
    PRIMARY KEY(playerid,id)
);
CREATE TABLE scoretype(
    scoreid integer primary key, 
    scorename varchar(50)
);
CREATE TABLE leaguescoretype(
    playerid integer,
    id integer,
    scoreid integer, 
    value double, 
    foreign key(playerid) references players(playerid), 
    foreign key(id) references leagues(id), 
    foreign key(scoreid) references scoretype(scoreid)
);

我想运行以下查询:

SELECT 
    players.playerid, 
    scoretype.scorename, 
    leaguescoretype.value 
FROM players,scoretype,leaguescoretype 
WHERE scoretype.scoreid = leaguescoretype.scoreid 
AND players.playerid = leaguescoretype.playerid 
AND players.playerid = 1 AND players.id = 1;

尝试在 EXPLAIN QUERY PLAN 下运行此查询,我得到:

SCAN TABLE leaguescoretype (~1000000 rows)
SEARCH TABLE players USING COVERING INDEX sqlite_autoindex_players(id=? AND playerid=?) (~1 rows)
SEARCH TABLE scoretype USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)

有没有办法提高这个查询的性能?

4

1 回答 1

1
CREATE INDEX ix_lst ON leaguescoretype (playerid)

我想应该有帮助。

如果您经常另外按 scoretype 搜索(使用相等检查),您可以这样创建它:

CREATE INDEX ix_lst ON leaguescoretype (playerid, scoreid)

看看SQLite 中的外键优化

编辑

顺便说一句,我会从桌面播放器的主键中删除 (playerid, id) 之一。外键在形式上(或至少在外观上)不正确,因为它仅引用 PK 列之一。虽然我认为这不会影响性能。

编辑 2 大多数关系数据库不会自动为外键约束创建索引。在许多情况下,这不是必需的。

以你的桌子scoretype为例。我假设此表上唯一的操作是非常罕见的插入。如果您从不leaguescoretype主要通过 scoretypeid 搜索,那么您不需要索引。

但是没有索引,只能通过扫描整个表才能找到表中的行。查看where条件和表格的大小。较大的表受益于索引。(一般来说,并非在所有情况下都有效。)

于 2013-11-14T08:02:19.390 回答