我需要减少表中每个用户的条目数,只留下每个用户的最新条目(比如10个)。它需要对子组中的条目进行编号(由user_id
定义)在MySQL中这是一项非常棘手的任务。我试过这样的事情:
SET
@prev_user := '',
@counter := 0
;
INSERT tmp_table_ordered
SELECT
@counter := CASE WHEN @prev_user = user_id THEN @counter + 1 ELSE 1 END AS counter,
@prev_user := user_id AS prev_user,
entry_id, timestamp, user_id, field_1, field_2
FROM table
ORDER BY user_id, timestamp DESC
;
在一些测试表(约2百万条记录)上,它与MyISAM(约20秒)相当不错,但是当我切换到InnoDB时,执行时间增加了一个数量级(约6分钟)。我尝试涉足索引,但它只是延长了任务。这段代码不是最理想的吗?是否有可能更好地解决问题?
编辑:
我很确定这是变量的处理会减慢我甚至没有测试过的查询速度。令我惊讶的是,减慢查询速度的变量并不是变量。它甚至不是选择慢,但是插入InnoDB表需要花费很多时间!如果只有目标表类型是MyIsam,则插入时间会很快。
再次编辑:
原始表格如下:
CREATE TABLE IF NOT EXISTS `table` (
`entry_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`user_id` int(11) unsigned NOT NULL,
`field_1` int(10) unsigned DEFAULT '0',
`field_2` int(11) unsigned NOT NULL,
PRIMARY KEY (`entry_id`),
) ENGINE=InnoDB DEFAULT CHARSET=ascii COLLATE=ascii_bin;
临时表创建如下:
CREATE TABLE `tmp_table_ordered` LIKE `table`;