I have this table for a cardgame with 2-4 players:
CREATE TABLE IF NOT EXISTS `cardgame` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`players` tinyint(1) unsigned NOT NULL DEFAULT '0',
`p1` mediumint(6) unsigned NOT NULL DEFAULT '0',
`p2` mediumint(6) unsigned NOT NULL DEFAULT '0',
`p3` mediumint(6) unsigned NOT NULL DEFAULT '0',
`p4` mediumint(6) unsigned NOT NULL DEFAULT '0',
`p1_state` tinyint(1) unsigned NOT NULL DEFAULT '0',
`p2_state` tinyint(1) unsigned NOT NULL DEFAULT '0',
`p3_state` tinyint(1) unsigned NOT NULL DEFAULT '0',
`p4_state` tinyint(1) unsigned NOT NULL DEFAULT '0',
/* other rows */,
`game_state` tinyint(1) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=79218 DEFAULT CHARSET=utf8;
I have to check all games, where I am a player. (my user_id is 1981 in the example)
mysql> EXPLAIN SELECT id FROM cardgame
WHERE ((p1=1981 AND p1_state=1) OR (p2=1981 AND p2_state=1)
OR (p3=1981 AND p3_state=1) OR (p4=1981 AND p4_state=1))
AND game_state < 7;
+----+-------------+----------+------+---------------+------+---------+------+-------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+------+---------------+------+---------+------+-------+-------------+
| 1 | SIMPLE | cardgame | ALL | NULL | NULL | NULL | NULL | 79208 | Using where |
+----+-------------+----------+------+---------------+------+---------+------+-------+-------------+
On which rows can I create indexes?
the p1, p1_state, p2.. p3.. p4, p4_state rows needs the index plus the game_state, but isn’t it too much?
Or I have to redesign the schema in some way?
Yes, normalise your schema:
Then your query becomes: