我有一张有点失控的桌子。我本身不是 DBA,但似乎记得一次性删除大量行会导致事务日志问题,在删除过程中妨碍整体系统性能等......
有没有一种有效的方法可以让我创建一个小批量删除记录以过度阻碍其他访问/性能并防止事务日志出现问题的作业?
这个过程可能会很慢,这会有所不同
对于其他上下文,删除条件将基于诸如...之类的内容where x like '%blah%'。此外,还有 1 个聚集索引和 5 个非聚集索引。
我遇到了一个问题,即同时执行的多个 MySQL 更新将锁定并需要几分钟才能完成。我正在使用 InnoDB,所以我很困惑为什么会发生这种情况,因为每次更新只更新 1 行。我还使用了一个 m2.4xlarge RDS 实例(它们是最大的)。

这就是我正在做的事情:我有一个包含大约 100M 行的表,其中“views”是一列(已编入索引),我想更新大约 1M 行的视图。在几个不同的服务器上,我有一个这样的循环,其中每个服务器都有自己的一组要更新的行(伪代码):
mysql("set autocommit=0");
mysql("start transaction");
foreach($rows as $row) {
mysql("update table set views=views+1 where id=$row[id]");
}
mysql("commit");
Run Code Online (Sandbox Code Playgroud)
这会遍历所有需要更新的行。当服务器数量很少时,它工作得很好,比如大约 4,但是当它增长到 10+ 时,更新开始立即挂在“更新”状态。没有说它正在等待锁定,它只是“更新”。这会发生大约 5 分钟,它最终将进行更新并继续循环并最终再次发生。
我不是在寻找进行更新的替代方法。拥有像 tmp 表和
update table,tmp_table set table.views = table.views+tmp_table.views where
table.id = tmp_table.id
Run Code Online (Sandbox Code Playgroud)
锁定所有正在更新的行,直到它们全部完成(可能需要几个小时),这对我不起作用。他们必须在这些可怕的循环中。
我想知道为什么他们会陷入“正在更新”状态,以及我能做些什么来防止它。
tldr; 有 10 个以上的“更新”循环最终会同时锁定所有正在完成的更新,原因不明,直到他们决定最终进行更新并继续循环,直到它在几秒钟后再次发生。
显示变量:http : //pastebin.com/NdmAeJrz
显示引擎 INNODB 状态:http : //pastebin.com/Ubwu4F1h
我们是一个数学家团队(即,没有 DBA 经验)。
我们在 SQL Server 2012 中有一个大型数据库。它有超过 2 TB 的数据(数百个表,每个表有数百万行和数百列宽)。每个月,我们都会收到一系列数据的添加和修订,这要求我们通过删除、替换或更新大部分或所有表来对数据库进行大量更新。
我们的工作主要集中在制定 SQL 逻辑来计算我们需要的结果。我们没有运行实时呼叫中心。我们根据需要应用了一些索引,我们对性能非常满意。
问题是日志文件。自然地,日志文件随着如此多的数据操作而增长和增长。我们的日志文件目前大约为 1 TB。我们有大量的磁盘空间,但不是无限的。
根据我们在 Internet 上的阅读,我们了解到日志文件对于事务完整性、回滚和恢复是必需的。但就我们的特定目的而言,我们并不关心这些。我们可能永远不会执行回滚,也永远不会尝试恢复。更糟糕的是,我们只需再次下载数据文件并从头开始创建一个新数据库。
我们真的只是希望日志文件消失并且永远不会回来。
我们将数据库恢复模式设置为简单,天真地认为这意味着“无恢复模式”,但我们很快就消除了这些幻想。
我们也明白有很多错误的事情不能做(分离、收缩等)。我们只是不知道正确的做法。
也许有人会建议我们设置日志文件增长的限制。但是,这留下了两个问题:(1) 我们如何摆脱已经存在的 1 TB?(2) 我们之前尝试过,当我们接近指定的限制时,我们开始在这里、那里和任何地方收到错误 9002(日志文件已满)。所以现在我们害怕应用大小限制。
我们如何在没有任何伤害的情况下告诉数据库“没有日志文件,请”?
我有一个分区表,在现实生活中它有 8000 万行。
出于测试目的,我在这里创建并分区了这个表。
当我运行以下查询时:
select * from countries
where visit >= '20110101'
and visit <= '20111231'
Run Code Online (Sandbox Code Playgroud)
正如您在此处和下图的查询计划中看到的那样,它使用分区消除,所以我知道我在做一些正确的事情。
我知道分区通常不是为了加速我的查询,它是一个管理功能,但是,它可以加速对大表的查询。
我将首先说明我不想要的东西。我不想从我的表中删除任何分区。
我想要的是?
我想以最快的方式从分区中删除所有数据:
有什么比这更快的吗? 不考虑批量删除
BEGIN TRANSACTION T1
DELETE
FROM dbo.countries WITH (TABLOCKX)
WHERE visit >= '20110101'
AND visit <= '20111231'
--COMMIT TRANSACTION T1
Run Code Online (Sandbox Code Playgroud)
sql-server ×3
delete ×2
concurrency ×1
innodb ×1
jobs ×1
mysql ×1
optimization ×1
partitioning ×1
t-sql ×1