Sql 删除语句花费的时间太长

Sql 删除语句花费的时间太长,sql,sql-server-2008-r2,Sql,Sql Server 2008 R2,我的sql Server 2008表有500多万条记录。我在一份声明中删除了400多万条记录。花了一个多小时。这是删除记录的最佳查询吗 我的删除查询 delete From [Table] where SUBSTRING([Column_YYY],1,CHARINDEX(N'',[Column_YYY])-1) = '4' 不,这不是最好的查询。您的子字符串以1开头,并且您正在与单个字符进行比较,'4'!要在ColumnYYY上使用索引,只需将其更改为LIKE子句,让索引快速查找前两个字符

我的sql Server 2008表有500多万条记录。我在一份声明中删除了400多万条记录。花了一个多小时。这是删除记录的最佳查询吗

我的删除查询

delete From [Table] 
where SUBSTRING([Column_YYY],1,CHARINDEX(N'',[Column_YYY])-1) = '4'

不,这不是最好的查询。您的子字符串以1开头,并且您正在与单个字符进行比较,
'4'
!要在ColumnYYY上使用索引,只需将其更改为LIKE子句,让索引快速查找前两个字符

delete [Table] 
where [Column_YYY] LIKE N'4%'
如果这不是针对表的80%,那么这是正确的,在这种情况下,SQL Server将完全扫描该表。为了防止tempdb空间问题或过大的事务(锁定),我会将其分解为几部分:

set nocount on
select 1;
while @@rowcount > 0
begin
    ;with x as (select top 100000 * from [Table] where [Column_YYY] LIKE N'4%')
    delete x;
end;

这是因为查询需要在数据库的每一行上运行substringfunction,以检查它是否符合条件。您应该始终避免使用WHERE子句上的函数。即使你有索引,它们也不会被使用

如果它占用了那么多并且是一个普通的操作,您可以考虑在DB上保留该值的结果并在其上创建索引

编辑: 与主要问题无关,但仍然是讨论的一部分。 索引用法:

这取决于你的电脑。你的查询没有问题,因为它没有使用
索引
。是的,我说过了。我提到,只有在列上保留substring函数的结果并直接进行检查时,才进行索引。如果您错了,请检查打印屏幕。它显示正在使用的索引。您正在使用的索引与%。我的回答是,数据应该被持久化,然后与实际要删除的字符串进行比较。我觉得这项工作非常有效,特别是在表上有一个日期字段的日期,例如,希望从第5个月删除所有内容,因此您不用运行delete,其中minth(column)=5,而是使用month(column)公式保留一个计算列,然后对其进行检查。如果你运行删除TestCindex,其中value =“{ 80”;在你的例子中,你会看到一个索引搜索,也许你太自满了,甚至不考虑我在说什么。我只是运行:设置RealCube 163840,然后更新TestCindex SETValue=“{ 80”,使80%的数据等于'''{80'。然后我休息rowcount并运行delete。我再次看到一个索引查找。如果你认为我在浪费你的时间,那就不要再回答了,但我正在为你提供证据,证明在这种特殊情况下使用了索引。在你的第一个查询中,是的,你是对的,但通过直接比较,SQL似乎正在使用对索引进行修改。