聚簇索引更新,如何仅在不同的列值更改索引?

时间:2018-03-14 11:15:26

标签: sql sql-server sql-server-2008 sql-server-2016 sql-execution-plan

我有桌子,

的例子
Id int primary key(clustered index)
Name varchar(255)not null (non-clustered index)
..
..
Other columns

我执行存储过程为

update table1 set table1.Name=isnull(@Name,table1.Name) ,( updating other columns) where Id=@Id;

很多次,姓名等于@Name; 在执行计划中,我看到enter image description here

如果我将存储过程更改为

update table1 set ( updating other columns) where Id=@Id;

我看到成本:15%

问题:

我需要在两种情况下改变这种情况

  1. table1.Name = @Name
  2. table1.Name<>名称。
  3. 在第一种情况下table1.Name没有更改值或索引没有更新和聚集索引更新成本15%;

    在第二种情况下table1.Name更改值和聚集索引更新成本50%。

    为什么索引在更新等值时会更新?

    我无法选择"姓名"和比较更新

    我知道创建varchar列索引并不是一个好主意

    更新

    使用更改查询更改名称列(执行CPU时间 200ms enter image description here

    更新查询不用更改名称列(执行CPU时间 70ms enter image description here

    更新

    问题已结束

1 个答案:

答案 0 :(得分:0)

为解决我的问题,我创建了一个Triger

CREATE TRIGGER [dbo].[trg_BeforeUpdateSubject] 
   ON  [dbo].[Subject] 
   INSTEAD OF UPDATE
AS 
BEGIN
    SET NOCOUNT ON;
        declare @old_val  nvarchar(255),@new_val nvarchar(255) ;
        select
@old_val=[Name]   
from deleted;
select 
@new_val=[Name]
from inserted;
     if (@old_val=@new_val)  
    BEGIN

        UPDATE 
            Subject
        SET
            set new values for other colums,
            Subject.DLC             =   GETDATE()
        FROM 
            inserted
        WHERE
            Subject.Id = inserted.Id            
    END ELSE
    BEGIN
        UPDATE 
            Subject
        SET
            Subject.Name = inserted.Name,
            set new values for other colums,
            Subject.DLC             =   GETDATE()
        FROM 
            inserted
        WHERE
            Subject.Id = inserted.Id                
    END

END

完美的工作。更新查询的平均值为90ms(CPU),旧值为200ms