在 MSSQL 中删除 table 中的旧条目

Delete old entries from table in MSSQL

a table 在我的 MSSQL 数据库中超过 500MB。我想删除最后 x 个条目,使 table 大小仅为 100MB。这应该是每周运行一次的任务。我该怎么做?

示例:

Table 在删除旧条目之前:

Table 删除旧条目后:

DELETE FROM TABLE_NAME WHERE date_column < '2018-01-01';

这将删除 2018 年 1 月之前输入的所有数据

如果您想删除最近 7 天的数据

delete from table_name WHERE date_column >= DATEADD(day,-7, GETDATE())

您可以使用 DATALENGTH 获取特定列中数据的大小。使用 window 函数,您可以汇总 运行 个 DATALENGTH 值。然后,您可以删除 table 中超过所需最大 table 大小的所有记录。这是一个例子:

-- Sample table with a VARBINARY(MAX) column
CREATE TABLE tmp (id INT IDENTITY(1,1) PRIMARY KEY, col VARBINARY(MAX))

-- Insert sample data - 20 bytes per row.
;WITH cte AS 
(
    SELECT 1 AS rn, HASHBYTES('sha1', 'somerandomtext') t
    UNION all 
    SELECT rn + 1, HASHBYTES('sha1', 'somerandomtext')
    FROM cte
    WHERE rn< 5000  
)
INSERT INTO tmp (col)
SELECT t FROM cte
OPTION (maxrecursion 0)

-- @total_bytes is the desired size of the table after the delete statement
DECLARE @total_bytes int = 200

-- Use the SUM window function to get a running total of the DATALENGTH
-- of the VARBINARY field, and delete when the running total exceeds
-- the desired table size.
-- You can order the window function however you want to delete rows
-- in the correct sequence.
DELETE t
FROM tmp t
INNER JOIN
(
    SELECT id, SUM(DATALENGTH(col)) OVER (ORDER BY id) total_size
    FROM tmp
)sq ON t.id = sq.id AND sq.total_size > @total_bytes

现在检查 tmp 中还剩下什么:10 行,"col" 列的总大小与@total_bytes 变量中指定的 200 字节大小相匹配。

更新:这是一个使用您的示例数据的示例:

CREATE TABLE tmp (id INT PRIMARY KEY, contact VARCHAR(100), country VARCHAR(25))
GO

INSERT INTO tmp VALUES 
(1, 'Maria Anders', 'Germany'),
(2, 'Francisco Chang', 'Mexico'),
(3, 'Roland Mendel', 'Austria'),
(4, 'Helen Bennett', 'UK'),
(5, 'Yoshi Tannamuri', 'Canada'),
(6, 'Giovanni Rovelli', 'Italy')
GO

-- @total_bytes is the desired size of the table after the delete statement
DECLARE @total_bytes INT = 40

-- Use the SUM window function to get a running total of the DATALENGTH
-- of the VARBINARY field, and delete when the running total exceeds
-- the desired table size.
-- You can order the window function however you want to delete rows
-- in the correct sequence.
DELETE t
FROM tmp t
INNER JOIN
(
    SELECT id, SUM(DATALENGTH(contact)) OVER (ORDER BY id)
        + SUM(DATALENGTH(country)) OVER (ORDER BY id) total_size
    FROM tmp
)sq ON t.id = sq.id AND sq.total_size > @total_bytes

SELECT * FROM tmp -- 2 rows left!