Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.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 有人对这两种方法中哪一种更适合大型删除有什么建议吗? 方法1: 方法2:_Sql_Query Optimization_Bulkinsert - Fatal编程技术网

Sql 有人对这两种方法中哪一种更适合大型删除有什么建议吗? 方法1: 方法2:

Sql 有人对这两种方法中哪一种更适合大型删除有什么建议吗? 方法1: 方法2:,sql,query-optimization,bulkinsert,Sql,Query Optimization,Bulkinsert,它们做不同的事情,在最上面的一项中,您将删除的行限制为符合条件的2000行。然而,在下面的一个示例中,您将select限制为返回2000行,而不考虑产品id,然后仅删除ProductID=@product\u id中的行。底部的一个具有更多的选择性和删除更少行的可能性 DELETE FROM ProductOrderInfo WHERE ProductId = @product_id AND FileNameCRC IN ( -- Now if @count is 2000 -- Yo

它们做不同的事情,在最上面的一项中,您将删除的行限制为符合条件的2000行。然而,在下面的一个示例中,您将select限制为返回2000行,而不考虑产品id,然后仅删除
ProductID=@product\u id
中的行。底部的一个具有更多的选择性和删除更少行的可能性

DELETE FROM ProductOrderInfo
WHERE ProductId = @product_id AND FileNameCRC IN 
(
  -- Now if @count is 2000
  -- You're guarentted *at most* 2000 rows
  -- *none* of which are guaranteed to have `ProductId = @product_id`

  SELECT TOP(@count) FileNameCRC
  FROM ProductOrderInfo WITH (NOLOCK)
  WHERE bCopied = 1 AND FileNameCRC = @localNameCrc
)

为什么要分块删除记录,而不是一次删除所有记录(没有
TOP
WAITFORDELAY
)?表中有3000多万条记录,我不想对插入和其他事务造成严重阻塞。如果我在内部选择中有和ProductId=@product\u id怎么办?那么查询至少是正确的,但它能实现什么呢?MVCC的工作方式是,
删除
获取行锁而不是表锁。在顶部,您为传递条件的行获取排他行锁,在底部,您为相关子查询中的所有行获取某种共享锁,这些行通过封装事务提升。这正是我所期望的,但肯定的答案是,不要担心它,让db来处理它。
DECLARE @count int
SET @count = 2000

DECLARE @rowcount int
SET @rowcount = @count

WHILE @rowcount = @count BEGIN

DELETE FROM ProductOrderInfo
WHERE ProductId = @product_id AND FileNameCRC IN 
(
SELECT TOP(@count) FileNameCRC
FROM ProductOrderInfo WITH (NOLOCK)
WHERE bCopied = 1 AND FileNameCRC = @localNameCrc
)

SELECT @rowcount = @@ROWCOUNT

WAITFOR DELAY '000:00:00.400'

END
DELETE FROM ProductOrderInfo
WHERE ProductId = @product_id AND FileNameCRC IN 
(
  -- Now if @count is 2000
  -- You're guarentted *at most* 2000 rows
  -- *none* of which are guaranteed to have `ProductId = @product_id`

  SELECT TOP(@count) FileNameCRC
  FROM ProductOrderInfo WITH (NOLOCK)
  WHERE bCopied = 1 AND FileNameCRC = @localNameCrc
)