如何根据到期时间查找 table 使行过期?
How do I expire rows based on a lookup table of expiry times?
如果我有两个 tables:
items
Id VARCHAR(26)
CreateAt bigint(20)
Type VARCHAR(26)
expiry
Id VARCHAR(26)
Expiry bigint(20)
items
table 包含项目的创建时间和类型。然后另一个 table、expiry
是一个查找 table 来说明某些类型应该持续多长时间。每天 运行 查询以确保删除已过期的项目。
目前这个查询是在我们的应用程序中编写的,作为编程代码:
for item in items {
expiry = expiry.get(item.Type)
if (currentDate() - expiry.Expiry > item.CreateAt) {
item.delete()
}
}
当我们只有几千个项目时这很好,但现在我们有数千万个项目需要大量时间 运行。有没有办法将其放入 SQL 语句中?
假设所有日期值实际上都是 UNIX 时间戳,您可以编写如下查询:
SELECT * -- DELETE
FROM items
WHERE EXISTS (
SELECT 1
FROM expiry
WHERE expiry.id = items.type
AND items.CreateAt + expiry.Expiry < UNIX_TIMESTAMP()
)
一旦确定查询选择了正确的行,请将 SELECT 替换为 DELETE。
如果存储的日期是自 UNIX 纪元以来的秒数,您可以使用此 PostgreSQL 查询:
DELETE FROM items
USING expiry
WHERE items.type = expiry.id
AND items.createat < EXTRACT(epoch FROM current_timestamp) - expiry.expiry;
适用于任何地方的标准 SQL 解决方案是
DELETE FROM items
WHERE items.createat < EXTRACT(epoch FROM current_timestamp)
- (SELECT expiry.expiry FROM expiry
WHERE expiry.id = items.type);
在 Postgre 中效率可能较低SQL。
您的代码越来越慢,因为您在数据库外部的表之间进行了连接。
第二个减慢的方面是你一个一个地删除项目。
因此,使用提供的紧凑删除语句是正确的解决方案。
看来您正在使用类似 python-sqlalchemy 的东西。那里的代码是这样的:
items.delete().\
where(items.c.type==\
select([expiry.c.id]).\
where(currentDate() - expiry.Expiry > item.c.CreateAt ))
如果我有两个 tables:
items
Id VARCHAR(26)
CreateAt bigint(20)
Type VARCHAR(26)
expiry
Id VARCHAR(26)
Expiry bigint(20)
items
table 包含项目的创建时间和类型。然后另一个 table、expiry
是一个查找 table 来说明某些类型应该持续多长时间。每天 运行 查询以确保删除已过期的项目。
目前这个查询是在我们的应用程序中编写的,作为编程代码:
for item in items {
expiry = expiry.get(item.Type)
if (currentDate() - expiry.Expiry > item.CreateAt) {
item.delete()
}
}
当我们只有几千个项目时这很好,但现在我们有数千万个项目需要大量时间 运行。有没有办法将其放入 SQL 语句中?
假设所有日期值实际上都是 UNIX 时间戳,您可以编写如下查询:
SELECT * -- DELETE
FROM items
WHERE EXISTS (
SELECT 1
FROM expiry
WHERE expiry.id = items.type
AND items.CreateAt + expiry.Expiry < UNIX_TIMESTAMP()
)
一旦确定查询选择了正确的行,请将 SELECT 替换为 DELETE。
如果存储的日期是自 UNIX 纪元以来的秒数,您可以使用此 PostgreSQL 查询:
DELETE FROM items
USING expiry
WHERE items.type = expiry.id
AND items.createat < EXTRACT(epoch FROM current_timestamp) - expiry.expiry;
适用于任何地方的标准 SQL 解决方案是
DELETE FROM items
WHERE items.createat < EXTRACT(epoch FROM current_timestamp)
- (SELECT expiry.expiry FROM expiry
WHERE expiry.id = items.type);
在 Postgre 中效率可能较低SQL。
您的代码越来越慢,因为您在数据库外部的表之间进行了连接。
第二个减慢的方面是你一个一个地删除项目。 因此,使用提供的紧凑删除语句是正确的解决方案。
看来您正在使用类似 python-sqlalchemy 的东西。那里的代码是这样的:
items.delete().\
where(items.c.type==\
select([expiry.c.id]).\
where(currentDate() - expiry.Expiry > item.c.CreateAt ))