到处都可以看到我应该在这样的情况下创建一个表索引:
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)
有没有办法提高此查询的效果?
答案 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
条件和表的大小。较大的表受益于索引。 (这通常是说并且在所有情况下都无效。)