我有以下mysql表:
CREATE TABLE `my_table` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`login` varchar(64) NOT NULL,
`state` enum("state_1","state_2","state_3") NOT NULL
PRIMARY KEY (`id`),
KEY `ix_date` (`date`),
KEY `ix_login_date` (`login`,`date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
此查询执行速度非常慢(超过10分钟):
SELECT
date,
@prev_login AS p_login,
(@prev_login := my_table.login) AS login,
@prev_state AS from_state,
(@prev_state := my_table.state) AS state
FROM my_table
JOIN (SELECT @prev_login := NULL) pl
JOIN (SELECT @prev_state := NULL) ps
ORDER BY login, date;
但是在删除(@prev_login := my_table.login) AS login
字符串后,查询在不到一秒的时间内完成:
SELECT
date,
@prev_login AS p_login,
@prev_state AS from_state,
(@prev_state := my_table.state) AS state
FROM my_table
JOIN (SELECT @prev_login := NULL) pl
JOIN (SELECT @prev_state := NULL) ps
ORDER BY login, date;
EXPLAIN为两种情况输出相同的result。为什么会发生这种情况以及如何加快第一次查询?
答案 0 :(得分:0)
我刚刚找到了解决方案。执行缓慢的原因是按login
字段排序。选择(@prev_login := my_table.login) AS login
字段会替换原始login
字段,因此索引不能用于排序。应该以这种方式重写查询:
SELECT
date,
@prev_login AS p_login,
(@prev_login := my_table.login) AS tmp_login,
login,
@prev_state AS from_state,
(@prev_state := my_table.state) AS state
FROM my_table
JOIN (SELECT @prev_login := NULL) pl
JOIN (SELECT @prev_state := NULL) ps
ORDER BY login, date;
P.S。我仍然不明白为什么EXPLAIN
没有显示这个问题。