Update takes too long

  • I am having a table with around 60000 rows.

    When updating, it takes long time to finish.

    My table design is as below.

    CREATE TABLE [dbo].[Entry_Jangad_Lot](

    [Srno] [bigint] IDENTITY(1,1) NOT NULL,

    [Kapan] [nvarchar](50) NOT NULL,

    [Lotno] [int] NOT NULL,

    [Quality] [nvarchar](50) NOT NULL,

    [Pcs] [int] NOT NULL,

    [Caret] [decimal](18, 2) NOT NULL,

    [JangadNo] [int] NOT NULL,

    [IssuedTo] [nvarchar](50) NULL,

    [IssuedDate] [nvarchar](50) NULL,

    [Status] [nvarchar](50) NULL,

    [ReceivedPcs] [int] NULL,

    [ReceivedCaret] [decimal](18, 2) NULL,

    [ReceivedDate] [nvarchar](50) NULL,

    [ReceivedType] [nvarchar](50) NULL,

    [Position] [nvarchar](50) NULL,

    [Process] [nvarchar](50) NULL,

    [MergedStatus] [nvarchar](50) NULL,

    [MergedToLotno] [int] NULL,

    CONSTRAINT [PK_Entry_Jangad_Lot_1] PRIMARY KEY CLUSTERED

    (

    [Srno] ASC

    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

    ) ON [PRIMARY]

    I am using following Procedure to update a table record.

    CREATE procedure [dbo].[sp_add_update_lot_receive]

    (

    @mode nvarchar(50),

    @Kapan nvarchar(50),

    @Lotno int,

    @ReceivedPcs int,

    @ReceivedCaret decimal(18,2),

    @ReceivedDate nvarchar(50),

    @ReceivedType nvarchar(50)

    )

    as

    if @mode='ADD'

    begin

    declare @srno int

    select @srno=srno from Entry_Jangad_Lot where Kapan=@Kapan

    and Lotno=@Lotno

    and Position='CURRENT'

    update Entry_Jangad_Lot set

    ReceivedPcs=@ReceivedPcs,

    ReceivedCaret=@ReceivedCaret,

    ReceivedDate=@ReceivedDate,

    ReceivedType=@ReceivedType,

    Status='RECEIVED'

    where srno=@srno

    --where Kapan=@Kapan

    --and Lotno=@Lotno

    --and Position='CURRENT'

    if @ReceivedType='POLISH'

    begin

    update Entry_Jangad_Lot set

    Process='POLISH'

    where srno=@srno

    --where Kapan=@Kapan

    --and Lotno=@Lotno

    --and Position='CURRENT'

    end

    else

    begin

    if @ReceivedType='TABLE'

    begin

    update Entry_Jangad_Lot set

    Process='TABLE'

    where srno=@srno

    --where Kapan=@Kapan

    --and Lotno=@Lotno

    --and Position='CURRENT'

    end

    else

    begin

    update Entry_Jangad_Lot set

    Process='NOTPOLISH'

    where srno=@srno

    --where Kapan=@Kapan

    --and Lotno=@Lotno

    --and Position='CURRENT'

    end

    end

    end

    GO

  • Are you updating those 60K rows one by one?

    If so than it's expected to be slow. You have to run a set-based update query.

    Igor Micev,My blog: www.igormicev.com

  • No

    I am not updating all rows.

    I am just updating a single row if where criteria matches with column 'kapan' and 'lotno'.

  • Ok,

    If you create an index on Lotno,Kapan and Position it should improve the selection in the where condition.

    where Lotno=@Lotno

    and Kapan=@Kapan

    and Position='CURRENT'

    Ensure Lotno is the first key column in the index:

    create non-clustered index IX_Entry_Jangad_Lot_index1 on Entry_Jangad_Lot(Lotno,Kapan,Position)

    Igor Micev,My blog: www.igormicev.com

  • As an aside, storing dates as nvarchar(50) is generally considered a really bad idea.

    The absence of evidence is not evidence of absence
    - Martin Rees
    The absence of consumable DDL, sample data and desired results is, however, evidence of the absence of my response
    - Phil Parkin

  • Still no improvements.

  • Igor Micev (4/27/2015)


    Ok,

    If you create an index on Lotno,Kapan and Position it should improve the selection in the where condition.

    where Lotno=@Lotno

    and Kapan=@Kapan

    and Position='CURRENT'

    Ensure Lotno is the first key column in the index:

    create non-clustered index IX_Entry_Jangad_Lot_index1 on Entry_Jangad_Lot(Lotno,Kapan,Position)

    No improvements after this also.

  • hemal_301080 (4/27/2015)


    Igor Micev (4/27/2015)


    Ok,

    If you create an index on Lotno,Kapan and Position it should improve the selection in the where condition.

    where Lotno=@Lotno

    and Kapan=@Kapan

    and Position='CURRENT'

    Ensure Lotno is the first key column in the index:

    create non-clustered index IX_Entry_Jangad_Lot_index1 on Entry_Jangad_Lot(Lotno,Kapan,Position)

    No improvements after this also.

    write the query properly first:

    CREATE procedure [dbo].[sp_add_update_lot_receive]

    (

    @mode nvarchar(50),

    @Kapan nvarchar(50),

    @Lotno int,

    @ReceivedPcs int,

    @ReceivedCaret decimal(18,2),

    @ReceivedDate nvarchar(50),

    @ReceivedType nvarchar(50)

    )

    AS

    IF @mode = 'ADD' -- shouldn't this be 'UPDATE'?

    UPDATE Entry_Jangad_Lot SET

    ReceivedPcs = @ReceivedPcs,

    ReceivedCaret = @ReceivedCaret,

    ReceivedDate = @ReceivedDate,

    ReceivedType = @ReceivedType,

    [Status] = 'RECEIVED',

    Process = CASE WHEN @ReceivedType = 'POLISH' THEN 'POLISH' WHEN @ReceivedType = 'TABLE' THEN 'TABLE' ELSE 'NOTPOLISH' END

    WHERE Kapan = @Kapan

    AND Lotno = @Lotno

    AND Position = 'CURRENT'

    GO

    Check the performance, if it's still unacceptably slow then post the actual execution plan.

    As Phil has already pointed out, your datatypes are awful. Is there anything you can do about them?

    “Write the query the simplest way. If through testing it becomes clear that the performance is inadequate, consider alternative query forms.” - Gail Shaw

    For fast, accurate and documented assistance in answering your questions, please read this article.
    Understanding and using APPLY, (I) and (II) Paul White
    Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden

  • You need to look to what the execution plan is telling you for how it's going to resolve this query. Your indexes are not being used or the statistics are out of date possibly.

    One concern I have is that you have a number of different UPDATE statements all within a single procedure. When this procedure is called, regardless of the parameters passed to it, all these statements will be compiled based on the parameters passed. This may be causing some of the plans to be created based on bad data. I would suggest treating an IF/ELSE construct like this as a wrapper procedure. Have each of your UPDATE statements in a different procedure. That way, each one gets its own unique plan when it gets called, not all at once.

    "The credit belongs to the man who is actually in the arena, whose face is marred by dust and sweat and blood"
    - Theodore Roosevelt

    Author of:
    SQL Server Execution Plans
    SQL Server Query Performance Tuning

  • ChrisM@Work (4/27/2015)


    hemal_301080 (4/27/2015)


    Igor Micev (4/27/2015)


    Ok,

    If you create an index on Lotno,Kapan and Position it should improve the selection in the where condition.

    where Lotno=@Lotno

    and Kapan=@Kapan

    and Position='CURRENT'

    Ensure Lotno is the first key column in the index:

    create non-clustered index IX_Entry_Jangad_Lot_index1 on Entry_Jangad_Lot(Lotno,Kapan,Position)

    No improvements after this also.

    write the query properly first:

    CREATE procedure [dbo].[sp_add_update_lot_receive]

    (

    @mode nvarchar(50),

    @Kapan nvarchar(50),

    @Lotno int,

    @ReceivedPcs int,

    @ReceivedCaret decimal(18,2),

    @ReceivedDate nvarchar(50),

    @ReceivedType nvarchar(50)

    )

    AS

    IF @mode = 'ADD' -- shouldn't this be 'UPDATE'?

    UPDATE Entry_Jangad_Lot SET

    ReceivedPcs = @ReceivedPcs,

    ReceivedCaret = @ReceivedCaret,

    ReceivedDate = @ReceivedDate,

    ReceivedType = @ReceivedType,

    [Status] = 'RECEIVED',

    Process = CASE WHEN @ReceivedType = 'POLISH' THEN 'POLISH' WHEN @ReceivedType = 'TABLE' THEN 'TABLE' ELSE 'NOTPOLISH' END

    WHERE Kapan = @Kapan

    AND Lotno = @Lotno

    AND Position = 'CURRENT'

    GO

    Check the performance, if it's still unacceptably slow then post the actual execution plan.

    As Phil has already pointed out, your datatypes are awful. Is there anything you can do about them?

    Agreed with you and I shortened the procedure.

  • Grant Fritchey (4/27/2015)


    You need to look to what the execution plan is telling you for how it's going to resolve this query. Your indexes are not being used or the statistics are out of date possibly.

    One concern I have is that you have a number of different UPDATE statements all within a single procedure. When this procedure is called, regardless of the parameters passed to it, all these statements will be compiled based on the parameters passed. This may be causing some of the plans to be created based on bad data. I would suggest treating an IF/ELSE construct like this as a wrapper procedure. Have each of your UPDATE statements in a different procedure. That way, each one gets its own unique plan when it gets called, not all at once.

    Yes you are correct and I have shortened the query as Chris said.

  • MANY things could be at fault here:

    1) triggers doing bad stuff

    2) constraints doing bad stuff

    3) blocking by other activity (I go with this by default for a 60K row tale without any other information)

    I note you never actually said how long each update was taking nor how long you expect it to take. What is the hardware? Is it virtualized?

    Assuming one update is running for multiple seconds at least you can use sp_whoisactive (awesome freebie from sqlblog.com) to determine what is happening during execution.

    Best,
    Kevin G. Boles
    SQL Server Consultant
    SQL MVP 2007-2012
    TheSQLGuru on googles mail service

  • You can use the NOLOCK hint for srno without worries because u're reading an identity value.

    Igor Micev,My blog: www.igormicev.com

  • Igor Micev (4/27/2015)


    You can use the NOLOCK hint for srno without worries because u're reading an identity value.

    Can you please explain that statement Igor??

    Best,
    Kevin G. Boles
    SQL Server Consultant
    SQL MVP 2007-2012
    TheSQLGuru on googles mail service

  • TheSQLGuru (4/27/2015)


    Igor Micev (4/27/2015)


    You can use the NOLOCK hint for srno without worries because u're reading an identity value.

    Can you please explain that statement Igor??

    Yeah. I'm unclear on it too.

    "The credit belongs to the man who is actually in the arena, whose face is marred by dust and sweat and blood"
    - Theodore Roosevelt

    Author of:
    SQL Server Execution Plans
    SQL Server Query Performance Tuning

Viewing 15 posts - 1 through 15 (of 35 total)

You must be logged in to reply to this topic. Login to reply