2014-04-17 110 views
2

我有以下MySQL表:为什么使用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),其中这种放缓是不适当的变量整理的结果,但我看不出它可以应用于我的情况。

+0

在查询中使用xmpp的目标/原因是什么? –

+0

@the_pete,这是一个错误的问题。应该有'my_table'。固定。 – citxx

+0

也许你应该考虑在登录列上索引你的32M记录表。 – StephaneM

回答

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不显示此问题。

相关问题