免责声明:请原谅我对数据库内部知识的缺乏。它是这样的:
我们运行一个应用程序(不是我们编写的),它在数据库的定期清理作业中存在很大的性能问题。查询如下所示:
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
我必须从 221+ 百万行表中删除 16+ 百万条记录,而且执行速度非常慢。
如果您分享使以下代码更快的建议,我将不胜感激:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
DECLARE @BATCHSIZE INT,
@ITERATION INT,
@TOTALROWS INT,
@MSG VARCHAR(500);
SET DEADLOCK_PRIORITY LOW;
SET @BATCHSIZE = 4500;
SET @ITERATION = 0;
SET @TOTALROWS = 0;
BEGIN TRY
BEGIN TRANSACTION;
WHILE @BATCHSIZE > 0
BEGIN
DELETE TOP (@BATCHSIZE) FROM MySourceTable
OUTPUT DELETED.*
INTO MyBackupTable
WHERE NOT EXISTS (
SELECT NULL AS Empty
FROM dbo.vendor AS v
WHERE VendorId = v.Id
);
SET @BATCHSIZE = @@ROWCOUNT;
SET @ITERATION = @ITERATION + …Run Code Online (Sandbox Code Playgroud) 我正在尝试删除所有重复项,但仅保留单个记录(更短的 ID)。以下查询删除重复项,但需要大量迭代才能删除所有副本并保留原始副本。
DELETE FROM emailTable WHERE id IN (
SELECT * FROM (
SELECT id FROM emailTable GROUP BY email HAVING ( COUNT(email) > 1 )
) AS q
)
Run Code Online (Sandbox Code Playgroud)
它的 MySQL。
数据线
CREATE TABLE `emailTable` (
`id` mediumint(9) NOT NULL auto_increment,
`email` varchar(200) NOT NULL default '',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=298872 DEFAULT CHARSET=latin1
Run Code Online (Sandbox Code Playgroud) 我有一个用于记录的表和一个用于清除DELETE 性能非常慢的旧数据的存储过程,这超出了我的理解。我正在寻找如何修改表或 DELETE 语句以在 LOB 数据上表现得相当好。或者,如果微软确认了这个问题——比如“我们已经用 SQL 服务器版本 x 解决了这个问题”,或者甚至“我们看到这性能很差,但它不是优先事项”——这也可以.
这是在 Microsoft SQL Server 2012 (SP3) 上运行的。下面基本上是我的实际表格和代码,只是稍微简化了:
CREATE TABLE [LOG_VALUE](
[ID] [int] IDENTITY(1,1) NOT NULL,
[VALUE] [varchar](max) NOT NULL,
[CHECKSUM] [int] NOT NULL,
[VALUE_LEN] [int] NOT NULL,
CONSTRAINT [PK_LOG_REQUEST] PRIMARY KEY CLUSTERED ([ID] ASC)
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)
有问题的删除是通过以下方式完成的:
WHILE (@@ROWCOUNT > 0)
DELETE TOP (100) [LOG_VALUE]
OUTPUT DELETED.[VALUE_LEN] INTO @DELETED_ROWS
WHERE [ID] IN (SELECT [ID] FROM @DELETE_IDS);
Run Code Online (Sandbox Code Playgroud)
基本的存储过程流程是:
我有一个包含数亿行的表,我需要从中删除数据。
现有的索引是最有效的。
但是,我可以使用现有索引通过使用ctid值查找要删除的行:
DELETE FROM calendar_event WHERE ctid IN
(SELECT ctid FROM calendar_event WHERE user_id = 5 LIMIT 100 FOR UPDATE)
Run Code Online (Sandbox Code Playgroud)
ctid在这种情况下依赖 的风险是什么?我最糟糕的情况是删除错误的行。
postgresql performance delete concurrency postgresql-performance
四天前,一个用户在一个有 400,000,000 行的表上运行了下面的命令。它仍在运行,日志文件的大小也在增加。
delete from [table-name]
Run Code Online (Sandbox Code Playgroud)
该表确实有一个未启用检查的外键约束,我知道另一个表中不存在任何行。
数据库正在启用“Is Read Committed Snapshot On”并处于简单恢复模式下运行。
在这运行了几个小时之后,我发出了一个终止会话命令,因为我们的日志文件磁盘空间不足。我添加了另一个日志文件以允许系统继续运行。
日志文件继续增长,当我使用 statusonly 运行 kill session 时,它返回此消息:
SPID 123: transaction rollback in progress. Estimated rollback completion: 0%. Estimated time remaining: 0 seconds.
Run Code Online (Sandbox Code Playgroud)
我不知道如何处理这个查询以使其回滚并且也只是了解正在发生的事情,任何人都可以建议我可以查看什么?
您在数据库中实现软删除的方法是什么?
理想情况下,该解决方案将允许
谢谢!
对 Prices 表中的大量行执行 DELETE 时,DELETE 会逐渐变慢。如果删除 15,000 行,它会在大约 15 秒内运行。20K 行需要 3 或 4 分钟。40,000 行需要 15 分钟,100,000 行运行一个多小时。
下面的 After DELETE 触发器使用可用价格类型的计数更新 Items 表。这用于计算价格以加快生产过程。
两个表都是InnoDB,我把innodb_buffer_pool_size更新为4G,没有效果。
我已经验证所有 SQL 语句都使用索引。Prices 表上有一个PriceType + ItemID 索引,ItemID 是Items 表的主键。
不幸的是,这个架构是由另一个应用程序确定的,我无法修改表结构。我可以修改触发器、索引等。无法更改该应用程序以直接更新 Items 表中的计数。
BEGIN
DECLARE iPriceTypeA INT;
DECLARE iPriceTypeB INT;
DECLARE iPriceTypeC INT;
SET iPriceTypeA = (SELECT COUNT(*) FROM Prices WHERE PriceType='A' AND ItemID=OLD.ItemID),
iPriceTypeB = (SELECT COUNT(*) FROM Prices WHERE PriceType='B' AND ItemID=OLD.ItemID),
iPriceTypeC = (SELECT COUNT(*) FROM Prices WHERE PriceType='C' AND ItemID=OLD.ItemID);
UPDATE …Run Code Online (Sandbox Code Playgroud) 我有两个表,每个表包含 2 亿条记录。我必须根据列中的整数值从它们中删除大约 7000 万条记录。
我使用以下脚本以 4000 块为单位删除它们:
DECLARE @BATCHSIZE INT, @ITERATION INT, @TOTALROWS INT, @MSG VARCHAR(500)
DECLARE @STARTTIME DATETIME, @ENDTIME DATETIME
SET NOCOUNT ON;
SET DEADLOCK_PRIORITY LOW;
SET @BATCHSIZE = 4000
SET @ITERATION = 0
SET @TOTALROWS = 0
WHILE @BATCHSIZE>0
BEGIN
SET @STARTTIME = GETDATE();
BEGIN TRANSACTION
DELETE TOP(@BATCHSIZE)
FROM [mydb].[dbo].tableA
WHERE [mydb].[dbo].tableA.Code not IN (
SELECT Code
FROM [mydb].[dbo].TableB)
SET @BATCHSIZE=@@ROWCOUNT
SET @ITERATION=@ITERATION+1
SET @TOTALROWS=@TOTALROWS+@BATCHSIZE
COMMIT TRANSACTION;
SET @ENDTIME = GETDATE();
SET @MSG = 'Iteration: ' + …Run Code Online (Sandbox Code Playgroud) delete ×10
mysql ×5
performance ×4
sql-server ×4
blob ×1
concurrency ×1
duplication ×1
index ×1
join ×1
kill ×1
mysql-5.6 ×1
optimization ×1
postgresql ×1
rollback ×1
trigger ×1