SQL选择查询锁定表

SQL选择查询锁定表,sql,sql-server-2012,Sql,Sql Server 2012,我有一个SQL查询访问传递查询,在运行时,它会锁定表,我不能对它做任何事情。它被锁定了一个多小时,因为表很大,数据库大小为250千兆。。SQL如下所示,但我希望有一种方法可以在不锁定表的情况下执行select查询 INSERT INTO BoydAmazonToday1 (LocalSKU, [Price Currency], Quantity) SELECT TOP (3000000) Inventory.LocalSKU, Inventor

我有一个SQL查询访问传递查询,在运行时,它会锁定表,我不能对它做任何事情。它被锁定了一个多小时,因为表很大,数据库大小为250千兆。。SQL如下所示,但我希望有一种方法可以在不锁定表的情况下执行select查询

INSERT INTO BoydAmazonToday1
                      (LocalSKU, [Price Currency], Quantity)
SELECT     TOP (3000000) Inventory.LocalSKU, Inventory.Price, InventorySuppliers.BoydQuantityAvailable
FROM         Inventory INNER JOIN
                      InventorySuppliers ON Inventory.LocalSKU = InventorySuppliers.LocalSKU INNER JOIN
                      Suppliers ON InventorySuppliers.SupplierID = Suppliers.SupplierID
WHERE     (NOT (Inventory.Price = 0)) AND (NOT (Inventory.Price IS NULL)) AND (InventorySuppliers.BoydQuantityAvailable > 49) AND (Inventory.Category LIKE '%Books%' OR
                      Inventory.Category LIKE '%DVDs%' OR
                      Inventory.Category LIKE '%Music%' OR
                      Inventory.Category LIKE '%VHS%') AND (Inventory.Discontinued = 0) AND (Suppliers.[Boyd-AmazonBackOrder] = 1) AND (InventorySuppliers.PrimarySupplier = 1) AND 
                      (NOT (Inventory.LocalSKU = '9780205309023u1')) AND 
                      (NOT (Inventory.LocalSKU = '9780205309023')) AND 
                      (NOT (Inventory.LocalSKU = '9781400052189')) AND 
                      (NOT (Inventory.LocalSKU = '9781400052189U1')) AND
                      (NOT (Inventory.LocalSKU = '9781435732865')) AND 
                      (NOT (Inventory.LocalSKU = '9781435732865U1'))
ORDER BY Inventory.Price ASC

您是否尝试过在事务上设置隔离级别


你也可以试试nolock

SELECT ... 
FROM Inventory (nolock) 
   INNER JOIN InventorySuppliers (nolock) ON Inventory.LocalSKU = InventorySuppliers.LocalSKU 
   INNER JOIN Suppliers (nolock) ON InventorySuppliers.SupplierID = Suppliers.SupplierID
我建议不要使用NOLOCK或将隔离级别更改为readuncommitted,除非您能够以某种方式保证在执行操作时没有其他进程尝试访问该表。这样的操作允许脏读,这实际上会破坏数据完整性。这就是表首先被锁定的原因

考虑寻找提高脚本效率和及时性的方法,而不是重写表锁定行为

一些考虑:

考虑重写WHERE子句,不要以%.%的形式包含通配符。这样做可能会导致查询引擎严重低效,谷歌称之为搜索引擎。 考虑利用表上的任何索引,特别是确保您参与索引字段。如果任何连接字段缺少索引,请考虑添加索引。
通过此查询,您将传递到哪些RDBMS?可能是SQL Server?是的,它是MSSQL 2012服务器。我对排名前300万的服务器很好奇。这是一个任意数字吗?可以进行批量更新,每次更新10000次,然后提交。看起来你可能正在尝试这样做?3000000确实发生了变化,我一直在考虑做一些批量更新。。我为代码的其他部分做批次。我没有尝试过,让我阅读它并返回给您。您也可以考虑在表上放置一个基于整数的类别字段,这样您就可以避免使用字符串搜索“%DVDS%”。您可以在插入行时添加它,然后使用查找表翻译1=DVD、2=Music等。我确实尝试过nolock,但没有。我确实在其他查询中使用nolock,这对提高效率有很大帮助。那么我建议你也阅读这篇文章。我也会查看链接,nolcok似乎有帮助。。仍然在重做部分代码。但是,正如您已经知道的,关于使用nolock的担忧不应该被忽略。如果我的回答是有帮助的,你能放弃吗?干杯。我知道其他进程将访问from表,但不是附加的那个进程。对于这个问题,脏读比锁定更重要,因为它很快就会被更新。我相信nolock会有所帮助。请记住,当您使用它时,为了保持数据的一致性,您正在避开SQL Server已有的机制。我通常考虑使用NoLoCK或改变隔离级别来克服性能问题,这是一个非常重要的反模式,应该避免的风险通常大于利益。我还是有点抽搐;-值得思考的是,可能导致查询执行缓慢的原因之一是正在执行的连接数。如果一个表这么大,听起来它可能更多地用于存储数据,而不是纯粹的事务性工作。创建一个包含主表和联接表中的所有记录的非最大化表可能会使您受益匪浅。这可以提高此类工作的绩效。
SELECT ... 
FROM Inventory (nolock) 
   INNER JOIN InventorySuppliers (nolock) ON Inventory.LocalSKU = InventorySuppliers.LocalSKU 
   INNER JOIN Suppliers (nolock) ON InventorySuppliers.SupplierID = Suppliers.SupplierID