在SQL Server中使用IN()删除3个表中的50行太慢了

问题描述 投票:1回答:2

我正在运行一个非常简单的删除语句查询。我有50个“文件”键,我想删除它们。我们的数据库架构如下所示:

  • 文件-UID(int)列是主键(具有唯一的聚集索引)

  • 版本-File列是File.UID的外键,DataLockerToken列是Cache.UID的外键]]

  • 缓存-UID(唯一标识符)列是主​​键(具有唯一的非聚集索引)

  • 版本必须索引我应用的SQL中的建议:

CREATE NONCLUSTERED INDEX [nc_VersionFile_DataLockerToken] 
ON [dbo].[Version] ([File] ASC) INCLUDE([DataLockerToken])

CREATE NONCLUSTERED INDEX [nc_VersionFile_UID] 
ON [dbo].[Version] ([File] ASC) INCLUDE([UID]) 

关系:文件1:M到版本1:1到缓存

这是我尝试执行的查询:

DELETE [Cache] 
FROM [Cache] c 
INNER JOIN Version v ON c.UID = v.DataLockerToken 
WHERE v.[File] IN ( 241647, ... 50 ids in total ..., 244038 );

DELETE Version 
WHERE [File] IN ( 241647, ... 50 ids in total ..., 244038 );

DELETE [File] 
WHERE UID IN ( 241647, ... 50 ids in total ..., 244038 );

这需要近1分钟的时间,我希望它会立即生效。 FileVersion表只是元数据,而Cache表实际上包含文件的二进制信息。

这里是执行计划的屏幕截图:

enter image description here

UPDATE

:必须在其中包含Cache表或二进制信息,因为如我所说,如果我在SQL Server Management Studio中运行查询,大约需要1分钟。然后,如果我再次在Management Studio或什至是C#控制台应用程序中运行完全相同的查询(相同的键,显然它们不存在),该查询将立即执行,因此除非存在某种我不希望使用的“查询缓存”认为没有,这表明事实是要删除的数据还是查询的问题?

有了这些最少的信息,任何人都可以在执行计划中看到并看到明显的问题吗?我通常依靠SQL在需要时给我一个索引提示(而且我知道您不能总是信任SQL),但这并不像数据库结构那么复杂。

让我知道是否有一个更好的平台可以就这个地方是否正确提出这个问题。

我正在运行一个非常简单的删除语句查询。我有50个“文件”键,我想删除它们。我们的数据库架构如下所示:File-UID(int)列是主键(带有...

sql sql-server sql-execution-plan
2个回答
1
投票

SQL将缓存查询计划,因此第二次会更快。您可以清理缓冲区并重新运行查询以查看区别(DBCC FREEPROCCACHE)


0
投票

对于50条记录,我建议切换到一个临时表,并对其进行联接,而不是使用较大的IN子句。这将使执行计划在每次运行时都是静态的,并且执行得更加一致。

© www.soinside.com 2019 - 2024. All rights reserved.