一个表中的两个索引,是仅用于where子句值得的第二个索引?

时间:2013-05-12 11:58:01

标签: mysql indexing

让我们说,我有以下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. 上的PRIMARY KEY
  3. 关于id的PRIMARY KEY和lastupdate上的INDEX
  4. PRIMARY KEY on(id,lastupdate)
  5. 哪一个会是最好的?

2 个答案:

答案 0 :(得分:1)

您应该在表matchesplayerid上添加索引,在表playerlastupdate上添加索引。

一个非常粗略的经验法则是,如果它是一个大表,你在WHEREJOIN子句中使用的内容应该有一个索引。

要获取更多信息,请使用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> 

答案 1 :(得分:0)

绝对数字2.主键用于唯一标识一行,而id属性就足够了,因此您不需要选项3.由于您的大多数查询看起来都像您所说的那样, lastupdate上的索引对于加速查询肯定会有用。