在表上创建索引

时间:2013-11-14 07:40:35

标签: sql sqlite indexing query-performance

到处都可以看到我应该在这样的情况下创建一个表索引:

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)

有没有办法提高此查询的效果?

1 个答案:

答案 0 :(得分:1)

CREATE INDEX ix_lst ON leaguescoretype (playerid)

应该对我有所帮助。

如果您经常通过scoretype搜索(使用等号检查),您可以像这样创建它:

CREATE INDEX ix_lst ON leaguescoretype (playerid, scoreid)

查看Foreign key optimization in SQLite

修改

BTW我会从桌面玩家的主键中删除(playerid,id)中的一个。外键正式(或至少在美容上)不正确,因为它只引用其中一个PK列。虽然我认为这不会影响性能。

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

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

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