为什么mysql查询用varchar变量执行速度极慢?

时间:2014-04-17 12:58:08

标签: mysql variables varchar

我有以下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。为什么会发生这种情况以及如何加快第一次查询?

UPD。我发现了问题(12)这种减速是不适当的变量整理的结果,但我认为没有办法可以应用对我来说。

1 个答案:

答案 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没有显示这个问题。