2015-11-13 30 views
0

我使用这下面的查询来更新我的表数据没有where子句来改善性能

Update BudCustomers 
set BudCustomers.ImportedRecord = ImportedRecord 
     ,BudCustomers.VersionID = @VersionId 
     ,BudCustomers.STATUSID = @StatusId 
     ,BudCustomers.MajorCode = EBIC.MajorCode 
FROM BudCustomers BCUST 
JOIN External_Blk_Itm_Contracts EBIC ON BCUST.LegalName = EBIC.CustomerName 
Where  BCUST.ImportedRecord <> @ImportedRecord 
     OR BCUST.STATUSID <> @StatusId 
     OR BCUST.MajorCode <> EBIC.MajorCode 

但由于性能问题,我不想使用WHERE子句,而不是我想要做的这些where子句中的事情重写查询加入本身但是我怀疑我是否正确。请为此与下面的查询进行比较。这是否会起作用?我很担心AND和OR条件加入它会工作相同

Update BudCustomers 
set BudCustomers.ImportedRecord = ImportedRecord 
     ,BudCustomers.VersionID = @VersionId 
     ,BudCustomers.STATUSID = @StatusId 
     ,BudCustomers.MajorCode = EBIC.MajorCode 
FROM BudCustomers BCUST 
JOIN External_Blk_Itm_Contracts EBIC ON BCUST.LegalName = EBIC.CustomerName AND BCUST.ImportedRecord <> @ImportedRecord OR BCUST.STATUSID <> @StatusId OR BCUST.MajorCode <> EBIC.MajorCode  
+0

混合AND和OR没有括号不是一个好主意。将BCIN重写为(BCUST.LegalName = EBIC.CustomerName AND BCUST.ImportedRecord <> @ImportedRecord)AND(BCUST.STATUSID <> @StatusId OR BCUST.MajorCode <> EBIC.MajorCode)。但我认为这对优化器是一样的。在SSMS中启用“包含实际执行计划”选项来检查两个查询。 – EKOlog

+1

将nonSARGable谓词移入连接不会有助于提高性能。你可以通过改变类似于(Row> Parameter OR Row

+0

我在查询中犯了一个错误。它应该是:“加入(BCUST.LegalName = EBIC.CustomerName)和(BCUST.ImportedRecord <> @ImportedRecord)或(BCUST.STATUSID <> @StatusId或BCUST.MajorCode <> EBIC.MajorCode))” – EKOlog

回答

1

不,你的第二个查询不会给出与第一个相同的答案。将其重写为仅限连接的方式是

... 
JOIN External_Blk_Itm_Contracts EBIC 
    ON BCUST.LegalName = EBIC.CustomerName 
    AND (BCUST.ImportedRecord <> @ImportedRecord 
      OR BCUST.STATUSID <> @StatusId 
      OR BCUST.MajorCode <> EBIC.MajorCode) 

或者您可以将其重写为仅限WHERE。在任何现代SQL服务器(包括SQL Server)上,所有三种选择都应该针对相同的查询计划进行优化,因此您的第一次尝试可能是最容易理解的。

如果您遇到性能问题,我会考虑您的索引是否适合于equijoin,并且就此而言连接是否正确......您是否真的使用“合法名称”客户作为主键,而不是一些分配或外部标识符?如果客户改变了他的名字怎么办?如果两个独立的客户碰巧拥有完全相同的名字会怎么样?

+0

CustomerName在表中是唯一的...不会有重复 – user1030181