Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL Delete语句执行时间过长_Sql_Sql Server_Sql Delete_Query Performance - Fatal编程技术网

SQL Delete语句执行时间过长

SQL Delete语句执行时间过长,sql,sql-server,sql-delete,query-performance,Sql,Sql Server,Sql Delete,Query Performance,我有下面的SQL delete语句。这将删除大约20000条记录,执行时间超过12分钟。在这里,我使用ROWNUMBER语句根据一些条件获取重复项。 任何修改脚本以更好地执行的想法。提前谢谢 delete from @TempTable where id in( select id from (select ROW_NUMBER() over(partition by Dep, NrInvoiceLine, OfficeId, pol,

我有下面的SQL delete语句。这将删除大约20000条记录,执行时间超过12分钟。在这里,我使用ROWNUMBER语句根据一些条件获取重复项。 任何修改脚本以更好地执行的想法。提前谢谢

delete from @TempTable where id in(
        select  id
        from 
        (select ROW_NUMBER() over(partition by  Dep,  NrInvoiceLine, OfficeId, pol,  pod,  PreCarr, WarehouseId, DestinationPrecarr,
         DestinationWarehouseId, PortTerminalId, Product, isnull(description, ''), ScaleCalcuationId, isnull(scalefrom, 0), isnull(scaleto, 0),  
         CurrencyCode, Base, ShippingLineID, ContainerId, AgentId order by type) Record, a.id
        from  @TempTable a where cast(Date as smalldatetime) = '2078-12-31 00:00:00' and IsDeleted = 0 and 
        (RO = 1 or RO=2) and (PP = 0 or PP = 2) 
        )as b   
        where b.Record !=1 )

在我看来,您需要将查询分解为更小的块。你正在执行的分区非常棒

是否有一种更简单的方法来实现您想要的输出?是否需要从此表中删除,或者是否可以创建另一个仅包含所需行的表,以便删除包含不感兴趣行的表?相同的结果不同的方法

还值得注意的是,创建表的性能通常比插入和删除行要好


编辑:我可以看到您正在试图减少已返回的副本。99%的情况下,这是一种清除错误编码的方法。找出引入副本的原因,并采取适当修复数据集所需的相关步骤

性能不佳的主要原因可能是,除非使用选项“重新编译”,否则表变量无法获得准确的行估计值。因此,您可能会得到一个基于估计的计划,即表变量包含的行比实际少得多

这里也不需要子查询

您应该会发现它执行得更快

WITH CTE
     AS (SELECT ROW_NUMBER() OVER(partition BY Dep, NrInvoiceLine, OfficeId, pol, pod, PreCarr, WarehouseId, DestinationPrecarr, DestinationWarehouseId, PortTerminalId, Product, isnull(description, ''), ScaleCalcuationId, isnull(scalefrom, 0), isnull(scaleto, 0), CurrencyCode, Base, ShippingLineID, ContainerId, AgentId ORDER BY type) Record,
                a.id
         FROM   @TempTable a
         WHERE  cast(Date AS SMALLDATETIME) = '2078-12-31 00:00:00'
                AND IsDeleted = 0
                AND ( RO IN ( 1, 2 ) )
                AND ( PP IN ( 0, 2 ) ))
DELETE FROM CTE
WHERE  Record > 1 
OPTION (RECOMPILE)
使用temp table而不是table变量,并创建以下索引

CREATE NONCLUSTERED INDEX NIX_temp
  ON #temptable (Date, IsDeleted, RO, PP)
  include (id, Dep, NrInvoiceLine, OfficeId, pol, pod, PreCarr, WarehouseId, DestinationPrecarr, DestinationWarehouseId, PortTerminalId, Product, description, ScaleCalcuationId, scalefrom, scaleto, CurrencyCode, Base, ShippingLineID, ContainerId, AgentId);
然后尝试像这样更改查询

;WITH cte
     AS (SELECT Row_number()
                  OVER(
                    partition BY Dep, NrInvoiceLine, OfficeId, pol, pod, PreCarr, WarehouseId, DestinationPrecarr, DestinationWarehouseId, PortTerminalId, Product, Isnull(description, ''), ScaleCalcuationId, Isnull(scalefrom, 0), Isnull(scaleto, 0), CurrencyCode, Base, ShippingLineID, ContainerId, AgentId
                    ORDER BY type) Record,
                a.id
         FROM   #temptable a
         WHERE  Date >= '2078-12-31 00:00:00'
                AND Date < Dateadd(dd, 1, '2078-12-31 00:00:00')
                AND IsDeleted = 0
                AND ( RO = 1
                       OR RO = 2 )
                AND ( PP = 0
                       OR PP = 2 ))
DELETE FROM cte
WHERE  Record > 1 

您可以添加select的解释计划吗?此表变量@TENTABLE中有多少条记录?如果要删除20K,我必须假设它至少有20001个表变量,并且表变量在该范围内的性能非常差。你能让它成为一个真正的临时表,前缀是,甚至是索引它吗?在这里,我根据where子句中提到的条件,使用partition by语句获取重复记录,然后尝试删除这些重复记录。实际上只有一个重复条目。但要从总共20k条记录中删除该记录,需要12分钟以上的时间才能执行。