I've just found the solution. The reason of slow execution is the sorting by login
field. Selecting of (@prev_login := my_table.login) AS login
field replaces the original login
field, so the index can't be used for ordering. The query should be rewritten in this way:
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. I still don't understand why EXPLAIN
doesn't show this issue.