0

たとえば、次の mysql テーブルがあるとします。

CREATE TABLE player (
    id int(9) unsigned NOT NULL DEFAULT 0 ,
    score MEDIUMINT(8) unsigned NOT NULL DEFAULT 0,
    signupdate DATE NOT NULL,
    lastupdate DATE NOT NULL
) DEFAULT CHARACTER SET utf8 ENGINE=InnoDB;

現在、id列に主キーがあります。lastupdate 列は毎日更新されます。更新されていない場合は、プレイヤーがアカウントを削除したことを意味します。これは、この列の基数が非常に低いことを意味します。また、フィールドと一致するリレーショナル テーブルがありmatchidplayeridmatchdate

私のクエリのほとんどは

SELECT id,score,signupdate FROM player 
JOIN matches ON matches.playerid = player.id 
WHERE lastupdate = '{today}'

だから、インデックスの3つのケースが頭に浮かぶ

  1. ID の主キー
  2. id の PRIMARY KEY と lastupdate の INDEX
  3. (id,lastupdate) の PRIMARY KEY

どれが一番いいでしょう??

4

2 に答える 2

1

テーブルの列にインデックスがあり、テーブルのmatches列にインデックスが必要です。playeridplayerlastupdate

非常に大まかな経験則として、WHEREandJOIN句で使用するものは、大きなテーブルの場合はインデックスを持つ必要があります。

explain使用されたインデックスの詳細を取得するには、ステートメントを使用できます。これがその外観です。explain最後のステートメントに注意してください。

mysql> CREATE TABLE player (
    ->     id int(9) unsigned NOT NULL DEFAULT 0 ,
    ->     score MEDIUMINT(8) unsigned NOT NULL DEFAULT 0,
    ->     signupdate DATE NOT NULL,
    ->     lastupdate DATE NOT NULL
    -> ) DEFAULT CHARACTER SET utf8 ENGINE=InnoDB;
Query OK, 0 rows affected (0.12 sec)

mysql> 
mysql> CREATE TABLE matches (
    ->     matchid int(9) unsigned NOT NULL DEFAULT 0 ,
    ->     playerid int(9) unsigned NOT NULL DEFAULT 0 ,
    ->     matchdate DATE NOT NULL
    -> ) DEFAULT CHARACTER SET utf8 ENGINE=InnoDB;
Query OK, 0 rows affected (0.22 sec)

mysql> 
mysql> SELECT id,score,signupdate FROM player 
    -> JOIN matches ON matches.playerid = player.id 
    -> WHERE lastupdate = now()
    -> ;
Empty set (0.00 sec)

mysql> 
mysql> explain
    -> SELECT id,score,signupdate FROM player 
    -> JOIN matches ON matches.playerid = player.id 
    -> WHERE lastupdate = '{today}'
    -> ;
+----+-------------+---------+------+---------------+------+---------+------+------+--------------------------------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows | Extra                          |
+----+-------------+---------+------+---------------+------+---------+------+------+--------------------------------+
|  1 | SIMPLE      | player  | ALL  | NULL          | NULL | NULL    | NULL |    1 | Using where                    |
|  1 | SIMPLE      | matches | ALL  | NULL          | NULL | NULL    | NULL |    1 | Using where; Using join buffer |
+----+-------------+---------+------+---------------+------+---------+------+------+--------------------------------+
2 rows in set, 2 warnings (0.00 sec)

mysql> CREATE INDEX player_idx_1 
    -> ON player (id)
    -> ;
Query OK, 0 rows affected (0.15 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> CREATE INDEX matches_idx_1 
    -> ON matches (playerid)
    -> ;
Query OK, 0 rows affected (0.16 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> 
mysql> explain SELECT id,score,signupdate FROM player  JOIN matches ON matches.playerid = player.id  WHERE lastupdate = '{today}';
+----+-------------+---------+------+---------------+---------------+---------+-----------------+------+-------------+
| id | select_type | table   | type | possible_keys | key           | key_len | ref             | rows | Extra       |
+----+-------------+---------+------+---------------+---------------+---------+-----------------+------+-------------+
|  1 | SIMPLE      | player  | ALL  | player_idx_1  | NULL          | NULL    | NULL            |    1 | Using where |
|  1 | SIMPLE      | matches | ref  | matches_idx_1 | matches_idx_1 | 4       | mysql.player.id |    1 | Using index |
+----+-------------+---------+------+---------------+---------------+---------+-----------------+------+-------------+
2 rows in set, 2 warnings (0.00 sec)

mysql> 

のインデックスを追加しますlastupdate

mysql> CREATE INDEX player_idx_2 
    -> ON player (lastupdate)
    -> ;
Query OK, 0 rows affected (0.13 sec)
Records: 0  Duplicates: 0  Warnings: 0
mysql> explain
    -> SELECT id,score,signupdate FROM player 
    -> JOIN matches ON matches.playerid = player.id 
    -> WHERE lastupdate = curdate()
    -> ;
+----+-------------+---------+------+---------------+---------------+---------+-----------------+------+-------------+
| id | select_type | table   | type | possible_keys | key           | key_len | ref             | rows | Extra       |
+----+-------------+---------+------+---------------+---------------+---------+-----------------+------+-------------+
|  1 | SIMPLE      | player  | ref  | player_idx_2  | player_idx_2  | 3       | const           |    1 |             |
|  1 | SIMPLE      | matches | ref  | matches_idx_1 | matches_idx_1 | 4       | mysql.player.id |    1 | Using index |
+----+-------------+---------+------+---------------+---------------+---------+-----------------+------+-------------+
2 rows in set (0.00 sec)

mysql> 
于 2013-05-12T12:05:29.190 に答える
0

間違いなく2番です。主キーは行を一意に識別するために使用され、id属性で十分なので、オプション3は必要ありません。ほとんどのクエリはあなたが言ったように見えるので、lastupdateにインデックスを持っていますクエリを高速化するのに間違いなく役立ちます。

于 2013-05-12T12:03:35.603 に答える