删除 MySQL 中超过 14 天的行
Delete rows older than 14 days in MySQL
Summary
我需要从超过 14 天的行中清除 table 的历史记录。
不是 MySQL 专家,我的搜索将我带到了这里:
delete
from SYS_VERROUS_POLICE
where idModificationPolice not in (
select distinct idModificationPolice
from SYS_VERROUS_POLICE
where date(dateHeureModification)
between curdate() and curdate() - interval 14 day
);
Thrown Exception
但后来我遇到了这个错误消息:
错误代码:1093。您不能在 FROM 子句中为更新指定目标 table 'SYS_VERROUS_POLICE'。
什么...
Context
MySQL 似乎在安全模式下运行,所以我无法在匹配日期的地方执行删除。
在安全模式下,如果我尝试仅使用日期字段进行删除,则不符合要求。
delete
from SYS_VERROUS_POLICE
where date(dateHeureModification) < curdate() - interval 14 day
Error Code: 1175. You are using safe update mode and you tried to update a table without a
WHERE that uses a KEY column
To disable safe mode, toggle the option in Preferences -> SQL Editor and reconnect.
0,00071 sec
我是不是漏掉了什么?
我不明白你为什么把它复杂化:
delete
from SYS_VERROUS_POLICE
where date(dateHeureModification)
<(curdate() - interval 14 day);
@Jean Dous 是正确答案。但只是为了解释您的查询中的问题是什么。您尝试检查与您正在更新的 table 相同的条件,这就像创建一个循环引用。
相反,您将 table 实现为子查询,以便您可以使用它。
delete
from SYS_VERROUS_POLICE
where idModificationPolice not in (
select distinct T.idModificationPolice
from (SELECT *
FROM SYS_VERROUS_POLICE) as T
where date(T.dateHeureModification)
between curdate() and curdate() - interval 14 day
);
我理解您关于使用安全模式的观点。如果您尝试对非索引表达式使用 UPDATE 或 DELETE,它会抱怨,因为它无法估计您是否会意外删除整个 table.
在 DATE(dateHeureModification) > ...
上使用表达式
自然是未索引的。 MySQL 无法对函数的结果进行索引查找。
您可以在删除查询中使用 LIMIT
使其满足安全更新模式。如果您使用 LIMIT
.
,MySQL 将其视为防止意外删除 table 中所有行的充分保护
DELETE
FROM SYS_VERROUS_POLICE
WHERE DATE(dateHeureModification) < (curdate() - INTERVAL 14 DAY)
LIMIT 1000;
无论如何,运行 以有限的批次删除是个好主意,这样它就不会创建太多锁或向撤消段添加太多锁。
只需继续循环执行 DELETE,一次删除 1000 行的批次,并在每批之后检查 rows-affected。当 rows-affected 达到 0 时停止循环。
另一个想法:我认为您真的不需要在 WHERE 子句中使用 DATE()
函数。所以你可以像下面那样执行 DELETE,并且它可以使用索引。此外,如果您在 dateHeureModification 上有索引,查询检查任何行应该会更快。
DELETE
FROM SYS_VERROUS_POLICE
WHERE dateHeureModification < (curdate() - INTERVAL 14 DAY)
LIMIT 1000;
Summary
我需要从超过 14 天的行中清除 table 的历史记录。
不是 MySQL 专家,我的搜索将我带到了这里:
delete
from SYS_VERROUS_POLICE
where idModificationPolice not in (
select distinct idModificationPolice
from SYS_VERROUS_POLICE
where date(dateHeureModification)
between curdate() and curdate() - interval 14 day
);
Thrown Exception
但后来我遇到了这个错误消息:
错误代码:1093。您不能在 FROM 子句中为更新指定目标 table 'SYS_VERROUS_POLICE'。
什么...
Context
MySQL 似乎在安全模式下运行,所以我无法在匹配日期的地方执行删除。
在安全模式下,如果我尝试仅使用日期字段进行删除,则不符合要求。
delete
from SYS_VERROUS_POLICE
where date(dateHeureModification) < curdate() - interval 14 day
Error Code: 1175. You are using safe update mode and you tried to update a table without a
WHERE that uses a KEY column
To disable safe mode, toggle the option in Preferences -> SQL Editor and reconnect.
0,00071 sec
我是不是漏掉了什么?
我不明白你为什么把它复杂化:
delete
from SYS_VERROUS_POLICE
where date(dateHeureModification)
<(curdate() - interval 14 day);
@Jean Dous 是正确答案。但只是为了解释您的查询中的问题是什么。您尝试检查与您正在更新的 table 相同的条件,这就像创建一个循环引用。
相反,您将 table 实现为子查询,以便您可以使用它。
delete
from SYS_VERROUS_POLICE
where idModificationPolice not in (
select distinct T.idModificationPolice
from (SELECT *
FROM SYS_VERROUS_POLICE) as T
where date(T.dateHeureModification)
between curdate() and curdate() - interval 14 day
);
我理解您关于使用安全模式的观点。如果您尝试对非索引表达式使用 UPDATE 或 DELETE,它会抱怨,因为它无法估计您是否会意外删除整个 table.
在 DATE(dateHeureModification) > ...
上使用表达式
自然是未索引的。 MySQL 无法对函数的结果进行索引查找。
您可以在删除查询中使用 LIMIT
使其满足安全更新模式。如果您使用 LIMIT
.
DELETE
FROM SYS_VERROUS_POLICE
WHERE DATE(dateHeureModification) < (curdate() - INTERVAL 14 DAY)
LIMIT 1000;
无论如何,运行 以有限的批次删除是个好主意,这样它就不会创建太多锁或向撤消段添加太多锁。
只需继续循环执行 DELETE,一次删除 1000 行的批次,并在每批之后检查 rows-affected。当 rows-affected 达到 0 时停止循环。
另一个想法:我认为您真的不需要在 WHERE 子句中使用 DATE()
函数。所以你可以像下面那样执行 DELETE,并且它可以使用索引。此外,如果您在 dateHeureModification 上有索引,查询检查任何行应该会更快。
DELETE
FROM SYS_VERROUS_POLICE
WHERE dateHeureModification < (curdate() - INTERVAL 14 DAY)
LIMIT 1000;