【发布时间】:2015-02-01 02:56:51
【问题描述】:
我有一个非常大的 MySQL 表(6800 万行),
我正在尝试使用以下查询每分钟保持一行:
delete bt
from table1 bt
join (select date, min(time) as time
from table1
group by date, hour(time), minute(time)
)
btt
on btt.date = bt.date
and hour(bt.time) = hour(btt.time)
and minute(bt.time) = minute(btt.time)
and btt.time <> bt.time
我的表有以下列
+----------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| date | varchar(11) | NO | | NULL | |
| time | varchar(12) | NO | | NULL | |
| gmt_offset | varchar(2) | YES | | NULL | |
| type | varchar(10) | YES | | NULL | |
| yield_b | varchar(10) | YES | | NULL | |
| yield_d | varchar(10) | YES | | NULL | |
+----------------+-------------+------+-----+---------+----------------+
查询运行超过 24 小时,当我运行时
SHOW FULL PROCESSLIST;
国家说
Creating sort index
这样的查询需要这么长时间是正常的吗?有什么方法可以加快速度吗?谢谢!
编辑:
Gordon 的回答是对的,只有一行小错误。这是正确的查询,确实比前一个查询快得多:
create table temp_table1 as
select t.*
from (select t1.*,
(@rn := if(@prevd = date and minute(time) = @prevm, @rn + 1,
if(@prevd := date, if(@prevm := minute(time), 1, 1), 1)
)
) as seqnum
from table1 t1 cross join
(select @rn := 0, @prevd := 0, @prevm := 0) vars
order by date, time
) t
where seqnum = 1;
【问题讨论】:
-
请澄清。从您的查询看来,您正试图在每个不同的分钟内删除除第一行(
time的最小值)之外的所有行。那是对的吗?请出示您的索引。有什么理由必须将date和time分开吗?如果您将它们组合成一个列,给它一个DATETIME数据类型,并为它建立索引,那么您将顺利找到一个有效的解决方案。 -
还有一个问题:
id值是否随日期+时间单调增加?也就是说,如果一个id大于另一个,是否保证其日期+时间与另一个相同或晚于另一个?