为什么使用varchar变量的mysql查询执行速度非常慢?

为什么使用varchar变量的mysql查询执行速度非常慢?,mysql,variables,varchar,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 `i

我有以下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分钟):

但是在删除作为登录名的
(@prev\u login:=my\u table.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;
解释两种情况下相同的输出。为什么会发生这种情况,以及如何加快第一次查询的速度


UPD。我发现了一些问题(,)其中这种减速是由于不适当的变量排序造成的,但我认为没有办法将其应用到我的案例中。

我刚刚找到了解决方案。执行缓慢的原因是按
login
字段排序。选择
(@prev_login:=my_table.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;

另外,我仍然不明白为什么
EXPLAIN
没有显示这个问题。

在您的查询中使用xmpp的目的/原因是什么?@皮特,这是问题中的一个错误。应该有
myu表
。也许你应该考虑在登录栏上索引你的32兆记录表。@ StephaneM,我看不到查询使用这种索引的原因。两个查询都只使用主键。
state
没有索引,但该列的相同计算速度很快。唯一的区别是类型。我唯一不清楚的是查询中的连接。。。如果删除联接,会发生什么情况?为什么你需要“加入”而不是“在哪里”?
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;