我有一个非常频繁更新的表,其中包含 2.4 亿行(并且还在增长)。每三小时插入 150 万行,删除 150 万行。当我将集群移动到 SSD 时,批量插入(使用复制)时间从 22 分钟减少到 2.3 分钟。删除时间也得到改善。我计划每两小时或每小时进行一次批量更新。
虽然现在的性能(在 SSD 之后)与更频繁的更新兼容,但我读过一些关于 SSD 死亡的恐怖故事,因为 NAND 耐久性有限加上写放大。由于 SSD 价格昂贵,我想尽可能地将它的消亡推迟到未来。因此我的问题是:在删除和随后的真空中磁盘文件到底发生了什么?我猜有两个磁盘写入,一个将行标记为已删除,另一个在清理时将其标记为可覆盖。如果不是删除和清空,而是在每次批量插入/删除时对表进行分区创建和删除表,我会尽量减少 SSD 的磨损吗?
我有一张有点失控的桌子。我本身不是 DBA,但似乎记得一次性删除大量行会导致事务日志问题,在删除过程中妨碍整体系统性能等......
有没有一种有效的方法可以让我创建一个小批量删除记录以过度阻碍其他访问/性能并防止事务日志出现问题的作业?
这个过程可能会很慢,这会有所不同
对于其他上下文,删除条件将基于诸如...之类的内容where x like '%blah%'。此外,还有 1 个聚集索引和 5 个非聚集索引。
我在 MySQL 中有一个表,每秒钟都有很多 INSERT 和 SELECT。并且每天都会批量删除一些旧数据。删除后是否需要重新索引表?我想提高性能。有人可以提出一些建议吗?使用“innodb”作为存储引擎。我需要改变它吗?我认为它更适合并发插入和选择。请提出您的建议。我需要重新索引吗?
提前致谢..
我们有一个“有机”的环境,这意味着人们在代码上堆积了十年,而几乎没有监督或文档。我使用的服务器有几个我认为不再使用的数据库;我很想删除它们,只留下我实际使用的三个。
在鲁莽的极端情况下,我可以禁用这些数据库并等待有人尖叫;另一方面,我可以让它们永远运行“以防万一”。在确定是否正在使用服务器方面,您发现哪些步骤很有价值,以及如何使用?
此外,您建议采取哪些步骤来确保在禁用系统的过程中,它们在一段时间内保持方便地可逆(例如,重命名对象而不是彻底删除它们)?
谢谢!
我想删除一个在AIX 6.0 OS中创建的oracle实例(oracle 10.2.0.4.0)。我知道我可以删除终端中的所有 dbf 和 ctl 文件,但我认为这不是最好的方法。我认为必须是一种更清洁的方式来做到这一点。
提前致谢。
我是 postgres 的新手,
我在实时服务器上有一个 2000 万行的表 - 我需要删除大部分行但不是全部。我想这样做而不影响访问此表的其他读/写进程(非常频繁)。
我有一种方法可以一次删除大约 100-400K 行块。在每次删除之间,我想让查询休眠 - 以便其他操作可以有机会访问此表。
我有代码,但我相信这个版本,它在查询运行的整个时间(所有睡眠)都锁定表。我怎样才能在进程休眠时真正释放表?谢谢!!
到目前为止我的代码:
CREATE SEQUENCE tmp_sq increment by 1 minvalue 1 maxvalue 53 start with 1;
DO $$
DECLARE
w_counter integer;
BEGIN
w_counter := (SELECT nextval('tmp_sq'));
while w_counter < 53 loop
raise notice 'Value: %', w_counter ;
w_counter := (SELECT nextval('tmp_sq'));
-- this way of breaking up the delete into chunks works for my table because of dates.
delete from table_a where date_part('week',my_date) = w_counter;
raise notice ' …Run Code Online (Sandbox Code Playgroud) 我的情况是这样的:
表 STOCK_ARTICLES:
ID *[PK]*
OTHER_DB_ID
ITEM_NAME
Run Code Online (Sandbox Code Playgroud)
表位置:
ID *[PK]*
LOCATION_NAME
Run Code Online (Sandbox Code Playgroud)
表 WORK_PLACE:
ID *[PK]*
WORKPLACE_NAME
Run Code Online (Sandbox Code Playgroud)
表 INVENTORY_ITEMS:
ID *[PK]*
ITEM_NAME
STOCK_ARTICLE *[FK]*
LOCATION *[FK]*
WORK_PLACE *[FK]*
Run Code Online (Sandbox Code Playgroud)
显然,INVENTORY_ITEMS 中的 3 个 FK 引用了相应其他表中的“ID”列。
这里的相关表是 STOCK_ARTICLE 和 INVENTORY_ITEMS。
现在有一个由几个步骤(SQL 脚本)组成的 SQL 作业,用于将上述数据库与另一个数据库(OTHER_DB)“同步” 。这项工作的步骤之一是“清理”。它从 STOCK_ITEMS 中删除其他数据库中没有具有相同 ID 的相应记录的所有记录。它看起来像这样:
DELETE FROM STOCK_ARTICLES
WHERE
NOT EXISTS
(SELECT OTHER_DB_ID FROM
[OTHER_DB].[dbo].[OtherTable] AS other
WHERE other.ObjectID = STOCK_ARTICLES.OTHER_DB_ID)
Run Code Online (Sandbox Code Playgroud)
但是这一步总是失败:
DELETE 语句与 REFERENCE 约束“FK_INVENTORY_ITEMS_STOCK_ARTICLES”相冲突。冲突发生在数据库“FIRST_DB”、表“dbo.INVENTORY_ITEMS”、“STOCK_ARTICLES”列中。[SQLSTATE 23000](错误 547)该语句已终止。[SQLSTATE 01000](错误 3621)。步骤失败。
所以问题是当它们被INVENTORY_ITEMS引用时,它不能从STOCK_ARTICLES中删除记录。但是这种清理需要起作用。这意味着我可能必须扩展清理脚本,以便它首先识别应该从 STOCK_ITEMS 中删除的记录,但不能因为相应的 ID 是从 INVENTORY_ITEMS 内部引用的。那么应该先删除INVENTORY_ITEMS里面的记录,然后再删除STOCK_ARTICLES里面的记录。我对吗?那么 …
我们在一个有 18 亿行的数据库上运行了一个删除查询。这次删除将删除 12 亿行。
事后看来,我们会一次将这个查询分解为 100m,但现在它已经运行了 24 小时,并且日志文件的大小为 2Tb,这似乎是日志文件所允许的最大大小。
数据库处于简单恢复模式。
有没有保存这个查询?还是我们只需要重新启动 SQL Server 看看会发生什么?数据库会无法使用吗?我们可以做些什么来尽可能干净地消除它?
免责声明:请原谅我对数据库内部知识的缺乏。它是这样的:
我们运行一个应用程序(不是我们编写的),它在数据库的定期清理作业中存在很大的性能问题。查询如下所示:
delete from VARIABLE_SUBSTITUTION where BUILDRESULTSUMMARY_ID in (
select BUILDRESULTSUMMARY_ID from BUILDRESULTSUMMARY
where BUILDRESULTSUMMARY.BUILD_KEY = "BAM-1");
Run Code Online (Sandbox Code Playgroud)
直截了当、易于阅读和标准 SQL。但不幸的是非常慢。解释查询显示VARIABLE_SUBSTITUTION.BUILDRESULTSUMMARY_ID未使用现有索引:
mysql> explain delete from VARIABLE_SUBSTITUTION where BUILDRESULTSUMMARY_ID in (
-> select BUILDRESULTSUMMARY_ID from BUILDRESULTSUMMARY
-> where BUILDRESULTSUMMARY.BUILD_KEY = "BAM-1");
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+-----------------------+-----------------+----------------------------------+---------+---------+------+---------+-------------+
| 1 | PRIMARY | VARIABLE_SUBSTITUTION | ALL | NULL | NULL | NULL | NULL | 7300039 …Run Code Online (Sandbox Code Playgroud) 这不起作用:
DELETE FROM topics AS t , posts AS p USING t INNER JOIN p
WHERE t.id=p.topic_id AND t.id = '5599';
Run Code Online (Sandbox Code Playgroud)
而这样做:
DELETE FROM topics, posts USING topics INNER JOIN posts
WHERE topics.id=posts.topic_id AND topics.id = '5599';
Run Code Online (Sandbox Code Playgroud)
在 DELETE 语句中使用表别名是无效的还是有其他方法?
我的目标是删除 ID 为 5599 的所有主题和相关帖子posts.topic_id= 5599
delete ×10
sql-server ×4
mysql ×3
postgresql ×2
index ×1
innodb ×1
instance ×1
jobs ×1
join ×1
maintenance ×1
mysql-5.6 ×1
optimization ×1
oracle-10g ×1
partitioning ×1
performance ×1
plpgsql ×1
storage ×1
t-sql ×1
vacuum ×1