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)

私が思うに役立つはずです。

スコアタイプ (等値チェックあり) でさらに検索することが多い場合は、次のように作成できます。

CREATE INDEX ix_lst ON leaguescoretype (playerid, scoreid)

SQLite での外部キーの最適化をご覧ください。

編集

ところで、テーブル プレーヤーのプライマリ キーから (playerid, id) の 1 つを削除します。外部キーは、PK 列の 1 つしか参照していないため、形式的に (または少なくとも表面的に) 正しくありません。これはパフォーマンスを損なうことはないと思いますが。

編集 2 ほとんどのリレーショナル データベースは、外部キー制約のインデックスを自動的に作成しません。そして多くの場合、これは必要ありません。

あなたのテーブルscoretypeを例に挙げてみましょう。このテーブルでの唯一のアクションは、非常にまれな挿入であると思います。leaguescoretype主に scoretypeid で検索しない場合は、インデックスは必要ありません。

ただし、インデックスがない場合、テーブル内の行は、テーブル全体をスキャンすることによってのみ見つけることができます。where条件とテーブルのサイズを見てください。大きなテーブルは、インデックスの恩恵を受けます。(これは一般的な話であり、すべての場合に有効というわけではありません。)

于 2013-11-14T08:02:19.390 に答える