Mysql 选择列值从上一行更改的行、用户变量、innodb

Mysql 选择列值从上一行更改的行、用户变量、innodb,mysql,database,variables,innodb,myisam,Mysql,Database,Variables,Innodb,Myisam,我有一个类似的问题 我适应的公认答案 CREATE TABLE `schange` ( `PersonID` int(11) NOT NULL, `StateID` int(11) NOT NULL, `TStamp` datetime NOT NULL, KEY `tstamp` (`TStamp`), KEY `personstate` (`PersonID`, `StateID`) ) ENGINE=InnoDB DEFAULT CHARSET=u

我有一个类似的问题

我适应的公认答案

CREATE TABLE `schange` (
    `PersonID` int(11) NOT NULL,
    `StateID` int(11) NOT NULL,
    `TStamp` datetime NOT NULL,
    KEY `tstamp` (`TStamp`),
    KEY `personstate` (`PersonID`, `StateID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


 CREATE TABLE `states` (
    `StateID` int(11) NOT NULL AUTO_INCREMENT,
    `State` varchar(100) NOT NULL,
    `Available` tinyint(1) NOT NULL,
    `Otherstatuseshere` tinyint(1) NOT NULL,
    PRIMARY KEY (`StateID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


SELECT 
    COALESCE((@statusPre <> s.Available), 1) AS statusChanged, 
    c.PersonID, 
    c.TStamp, 
    s.*, 
    @statusPre := s.Available  
FROM schange c 
INNER JOIN states s USING (StateID), 
(SELECT @statusPre:=NULL) AS d 
WHERE PersonID = 1 AND TStamp > "2012-01-01" AND TStamp < "2013-01-01"
ORDER BY TStamp ;
查询本身在测试中工作得很好,有了正确的临时表组合,我可以在几乎没有时间的情况下从大量数据中生成具有每日总和可用性的报告。 当我发现使用MyISAM引擎的表(我们已经完全放弃了该引擎)重新创建表以使用InnoDB时,真正的问题出现了,并注意到查询不再像预期的那样工作

在一些猛击之后,我发现MyISAM似乎在更新@statusPre之前选择statusChanged,然后遍历每一行的列,而InnoDB似乎首先进行所有变量赋值,然后才填充结果行,不管赋值发生在select或where子句中,函数中的联合、更大等、子查询或其他

在一个没有变量的查询中尝试实现这一点似乎总是以同样的方式结束,子查询需要成倍增加的时间来处理集合中的行数越多,从而导致在获取一个状态的开始和结束事件时需要花费数分钟或数小时的等待,而一份完成的报告应包括多个项目的每日总和

这种类型的查询可以在InnoDB引擎上工作吗?如果可以,应该如何进行? 或者是支持WITH语句的数据库产品的唯一可行选择?

删除 密钥personstate PersonID,StateID 解决了这个问题。 不知道为什么会这样,但实际上并不需要时间戳键,时间戳键更重要,可以很好地加快查询速度