我有一个查询运行得很慢。
大约需要7秒钟。
但是,如果我从查询中删除“and timestamp>20130201”,则只需不到400毫秒即可运行。
我以为timestamp字段可能没有索引,但它是索引字段,所以我想知道为什么向查询添加这样的日期会导致查询速度变慢?
如果可以的话,我不想删除查询的那一部分,但是我不明白为什么在查询时会慢得多。
查询:
select p1_score,p2_score,p3_score,p4_score from game where (p1_user_id='$uid' or p2_user_id='$uid' or p3_user_id='$uid' or p4_user_id='$uid') and turn=0 and timestamp > 20130201
说明:
1 SIMPLE game range p1_user_id,p2_user_id,p3_user_id,p4_user_id,turn,timestamp timestamp 4 NULL 51486 Using where
创建SQL:
CREATE TABLE `game` (
`id` bigint(10) NOT NULL AUTO_INCREMENT,
`p1_user_id` varchar(100) NOT NULL DEFAULT '',
`p2_user_id` varchar(100) NOT NULL DEFAULT '',
`p3_user_id` varchar(100) NOT NULL DEFAULT '',
`p4_user_id` varchar(100) NOT NULL DEFAULT '',
`player_one_name` varchar(100) DEFAULT NULL,
`player_two_name` varchar(100) DEFAULT NULL,
`player_three_name` varchar(100) DEFAULT NULL,
`player_four_name` varchar(100) DEFAULT NULL,
`player_one_email` varchar(100) DEFAULT NULL,
`player_two_email` varchar(100) DEFAULT NULL,
`player_three_email` varchar(100) DEFAULT NULL,
`player_four_email` varchar(100) DEFAULT NULL,
`p1_score` bigint(10) DEFAULT '0',
`p2_score` bigint(10) DEFAULT '0',
`p3_score` bigint(10) DEFAULT '0',
`p4_score` bigint(10) DEFAULT '0',
`game_name` varchar(255) DEFAULT NULL,
`players` smallint(1) DEFAULT NULL,
`turn` varchar(10) DEFAULT NULL,
`turn_num` smallint(10) DEFAULT '0',
`layout` longtext,
`verify` varchar(40) DEFAULT NULL,
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`message` longtext,
`tourn` smallint(5) NOT NULL DEFAULT '0',
`round` smallint(4) NOT NULL DEFAULT '0',
`tourn_id` varchar(20) NOT NULL DEFAULT '',
`move_history` longtext NOT NULL,
`next_turn` varchar(50) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `tourn` (`tourn`),
KEY `by_player_one_email` (`player_one_email`(10)),
KEY `by_player_two_email` (`player_two_email`(10)),
KEY `by_player_three_email` (`player_three_email`(10)),
KEY `by_player_four_email` (`player_four_email`(10)),
KEY `p1_user_id` (`p1_user_id`),
KEY `p2_user_id` (`p2_user_id`),
KEY `p3_user_id` (`p3_user_id`),
KEY `p4_user_id` (`p4_user_id`),
KEY `turn` (`turn`),
KEY `verify` (`verify`),
KEY `next_turn` (`next_turn`),
KEY `timestamp` (`timestamp`),
KEY `round` (`round`),
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
最佳答案
如果没有时间戳条件的查询运行得很快,那么理论上,将其作为子查询运行得也应该同样快。假设性能差异是由查询优化器中的错误引起的,则应该具有相同的性能:
SELECT * FROM (query without timestamp condition) t WHERE timestamp > 20130201
这当然只是猜测。如果不知道查询的表、查询和解释计划,就不可能给出问题的明确答案。
更新:现在我们有了表描述和解释计划,我们看到查询使用的是
timestamp
列上定义的索引。显然,这个索引不适合这个查询,因为查询最终检查了超过51000行。您可以使用索引提示tell MySQL that a different index might be better。例如,这应该使用用户id上的索引,它应该像查询一样执行,而不限制
timestamp
:SELECT ... from game USE INDEX (p1_user_id,p2_user_id,p3_user_id,p4_user_id)
WHERE ...
或者,您可以让MySQL忽略
timestamp
上的索引,因此它应该使用其他更合适的索引:SELECT ... from game IGNORE INDEX (timestamp) WHERE ...
创建多列索引可能会使查询受益。
关于mysql - MySQL查询慢,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15600790/