Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8027247
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 4, 20262026-06-04T23:45:12+00:00 2026-06-04T23:45:12+00:00

I am supposed to remove whole rows and part of XML-documents from a table

  • 0

I am supposed to remove whole rows and part of XML-documents from a table with an XML column based on a specific value in the XML column. However the table contains millions of rows and gets locked when I perform the operation. Currently it will take almost a week to clean it up, and the system is too critical to be taken offline for so long.

Are there any ways to optimize the xpath expressions in this script:

declare @slutdato datetime = '2012-03-01 00:00:00.000'
declare @startdato datetime = '2000-02-01 00:00:00.000'
declare @lev varchar(20) = 'suppliername'
declare @todelete varchar(10) = '~~~~~~~~~~'

CREATE TABLE #ids (selId int NOT NULL PRIMARY KEY)
INSERT into #ids
select id from dbo.proevesvar
WHERE leverandoer = @lev
and proevedato <= @slutdato
and proevedato >= @startdato


begin transaction  /* delete whole rows */
delete from dbo.proevesvar
where id in (select selId from #ids)
and ProeveSvarXml.exist('/LaboratoryReport/LaboratoryResults/Result[Value=sql:variable(''@todelete'')]') = 1
and Proevesvarxml.exist('/LaboratoryReport/LaboratoryResults/Result[Value!=sql:variable(''@todelete'')]') = 0

commit
go

begin transaction /* delete single results */
UPDATE dbo.proevesvar SET ProeveSvarXml.modify('delete /LaboratoryReport/LaboratoryResults/Result[Value=sql:variable(''@todelete'')]')
where id in (select selId from #ids)
commit
go

The table definitions is:

CREATE TABLE [dbo].[ProeveSvar](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [CPRnr] [nchar](10) NOT NULL,
    [ProeveDato] [datetime] NOT NULL,
    [ProeveSvarXml] [xml] NOT NULL,
    [Leverandoer] [nvarchar](50) NOT NULL,
    [Proevenr] [nvarchar](50) NOT NULL,
    [Lokationsnr] [nchar](13) NOT NULL,
    [Modtaget] [datetime] NOT NULL,
    CONSTRAINT [PK_ProeveSvar] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY],
 CONSTRAINT [IX_ProeveSvar_1] UNIQUE NONCLUSTERED 
(
    [CPRnr] ASC,
    [Lokationsnr] ASC,
    [Proevenr] ASC,
    [ProeveDato] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

The first insert statement is very fast. I believe I can handle the locking by committing 50 rows at a time, so other requests can be handled in between my transactions.
The total number of rows for this supplier is about 5.5 million and the total rowcount in the table is around 13 million.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-04T23:45:13+00:00Added an answer on June 4, 2026 at 11:45 pm

    I’ve not really used xpath within SQL server before, but something which stands out is that you’re doing lots of reads and writes in the same command (in the second statement). If possible, change your queries to..

    CREATE TABLE #ids (selId int NOT NULL PRIMARY KEY)
    INSERT into #ids
    select id from dbo.proevesvar
    WHERE leverandoer = @lev
    and proevedato <= @slutdato
    and proevedato >= @startdato
    and ProeveSvarXml.exist('/LaboratoryReport/LaboratoryResults/Result[Value=sql:variable(''@todelete'')]') = 1
    and Proevesvarxml.exist('/LaboratoryReport/LaboratoryResults/Result[Value!=sql:variable(''@todelete'')]') = 0
    
    
    begin transaction  /* delete whole rows */
    delete from dbo.proevesvar
    where id in (select selId from #ids)
    

    This means that the first query will only create the new temporary table, and not write anything back, which will take slightly longer than your original, but the key thing is that your second query will ONLY be deleting records based on what’s in your temporary table.

    What you’ll probably find is because it’s deleting records, it’s constantly re-building indices, and causing the reads to also be slower.

    I’d also delete/disable any indices/constraints that don’t actually help your query run.

    Also, you’re creating your clustered primary key on the ID, which isn’t always the best thing to do. Especially if you’re doing lots of date scans.

    Can you also view the estimated execution plan for the top query, it would be interesting to see the order in which it checks the conditions. If it’s doing the date first, then that’s fine, but if it’s doing the xpath before it checks the date, you might have to separte it into 3 queries, or add a new clustered index on ‘proevedato,id’. This should force the query to only run the xpath for records which actually match the date.

    Hope this helps.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I want to remove a suppose control whose type is of border, from the
Basically the program is supposed to create a round table of executives, with a
Background for understanding the question I'm currently designing a simple, light-weight (application-specific) message-based API
I am having a HTML table with 5 rows (say) which is being displayed
I've got a table that is supposed to track days and costs for shipping
I'm supposed to implement a function that erases a range of values from containers.
How are you supposed to programatically detect when the remote modem on your call
Supposed I have the following string: string str = <tag>text</tag>; And I would like
Supposed I have a class called TrafficLight and I would like to have a
Supposed that I have two arrays: Dim RoomName() As String = {(RoomA), (RoomB), (RoomC),

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.