I need to delete all indexes (other than clustered index) of a table and rebuild them all.
For example, I have the following structure:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[SP6](
[SP6_REGCLI] [char](10) NOT NULL,
[SP6_REGEMP] [char](4) NOT NULL,
[SP6_FILIAL] [char](2) NOT NULL,
[SP6_CODDEP] [char](9) NOT NULL,
[SP6_DESCRI] [char](40) NULL,
[SP6_FOLGA] [char](1) NULL,
[SP6_HESOAU] [char](1) NULL,
[SR_RECNO] [numeric](15, 0) IDENTITY(1,1) NOT NULL,
CONSTRAINT [PK__SP6] PRIMARY KEY NONCLUSTERED
(
[SR_RECNO] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE CLUSTERED INDEX [SP6_SR] ON [dbo].[SP6]
(
[SR_RECNO] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
CREATE NONCLUSTERED INDEX [SP601_1_REG] ON [dbo].[SP6]
(
[SP6_REGCLI] ASC,
[SP6_REGEMP] ASC,
[SP6_FILIAL] ASC,
[SP6_CODDEP] ASC,
[SR_RECNO] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
CREATE NONCLUSTERED INDEX [SP602_2_REG] ON [dbo].[SP6]
(
[SP6_REGCLI] ASC,
[SP6_REGEMP] ASC,
[SP6_FILIAL] ASC,
[SP6_DESCRI] ASC,
[SR_RECNO] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
In this structure I have to delete all the NONCLUSTERED indexes (i.e. the index SP6_SR won't be deleted).
I need to do this because I have to change the size of some columns that is part of some indexes. For example, if I try to change the size of the colum SP6_DESCRI to Char(50) an error occurs because the column is part of index SP602_2_REG.
I think that if I delete all indexes of a table, change the size of columns desired and then rebuild all indexes, everything will be fine.
Can anyone help me please?
Thank you so much!
Related
Trying to determine why a particular query is notably slow. This query shares features with other notably slow queries, so speeding this one up will give me the tools to speed other queries up.
It's a bit of a complicated query, with 5 INNER JOINs, but the first part that seems odd to me is that my first join is underestimating the memory grant, which is causing a spill during the Hash Match.
The first part of the query is estimating the number of rows returned for the query as 98,706, which is off by a factor of 10 (the true number of rows for that query is 874,215.)
I ran sp_BlitzIndex on the IRItemAnswer_Info table, and confirmed that for the key being used by the table (IRItemAnswerInfo_DGItemID_AnswerBoolean) and the parameter in question (Leading Column Name DGItemID = 1907) the statistic is correct (874,215 rows). This is because we run a UPDATE STATISTICS IRItemAnswer_Info WITH FULLSCAN weekly during off-hours, to ensure that statistics are as correct as can reasonably be.
What else can I look to as the possible cause of the bad rows estimate? The Index exactly covers the query, so I'm confused why the estimate is off, causing an insufficient memory grant?
IRItemAnswer_Info does have one significantly large column: AnswerValue, designed to hold rich-text content. The other columns are much more reasonably sized.
CREATE TABLE [dbo].[IRItemAnswer_Info](
[ItemAnswerSID] [dbo].[T_SidDom] IDENTITY(1,1) NOT NULL,
[DGItemID] [dbo].[T_SidDom] NULL,
[IncidentID] [dbo].[T_SidDom] NULL,
[IRPhaseID] [dbo].[T_SidDom] NULL,
[AnswerTypeID] [dbo].[T_SidDom] NULL,
[AnswerSourceID] [dbo].[T_SidDom] NULL,
[AnswerValue] [varchar](8000) NULL,
[AnswerCode] [dbo].[T_CodeDom] NULL,
[AnswerLabel] [dbo].[T_LabelDom] NULL,
[IndividualReviewFlag] [dbo].[T_BooleanDom] NULL,
[ModifiedDate] [datetime] NULL,
[ModifiedBy] [dbo].[T_UseridDom] NULL,
[AnswerBoolean] [dbo].[T_BooleanDom] NULL,
[CallingItemID] [dbo].[T_SidDom] NULL,
[ClearOnDeident] [dbo].[T_BooleanDom] NULL,
[Deidentified] [dbo].[T_BooleanDom] NULL,
[Answer_AdditionalInfo] [dbo].[T_DescDom] NULL,
[SubRowPosition] [tinyint] NULL
)
The Actual Execution Plan for the full query that I'm troubleshooting
DBCC SHOW_STATISTICS (IRItemAnswer_Info,IRItemAnswerInfo_DGItemID_AnswerBoolean) WITH DENSITY_VECTOR
returns the following:
It's a large query with lots of indexes, so I'll do my best here:
CREATE NONCLUSTERED INDEX [IRItemAnswerInfo_DGItemID_AnswerBoolean] ON [dbo].[IRItemAnswer_Info]
(
[DGItemID] ASC,
[AnswerBoolean] ASC
)
INCLUDE([IncidentID],[AnswerSourceID]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [Incident_Info_Date_IDPhaseIDTimeFacDeptCreated] ON [dbo].[Incident_Info]
(
[IncidentDate] ASC
)
INCLUDE([IncidentSid],[IRPhaseId],[IncidentTime],[FacilityId],[DepartmentId],[CreatedByUserID]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [indIncidentType_XRef_IncidentTypeNodeID] ON [dbo].[IncidentType_XRef]
(
[IncidentTypeNodeID] ASC
)
INCLUDE([IncidentID]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [indIRAlternative_Info_AltSID] ON [dbo].[IRAlternative_Info]
(
[AltSID] ASC
)
INCLUDE([AltLabel]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [indIncidentTypeHierarchy_Code_NodeLeftNodeRightNodeLevel] ON [dbo].[IncidentTypeHierarchy_Code]
(
[NodeLeft] ASC,
[NodeRight] ASC,
[NodeLevel] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
ALTER TABLE [dbo].[IncidentTypeHierarchy_Code] ADD CONSTRAINT [PK_IncidentTypeHierarchy_Code] PRIMARY KEY CLUSTERED
(
[IncidentTypeNodeSID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
ALTER TABLE [dbo].[IRDGroupItem_Info] ADD CONSTRAINT [PK_IRDGroupItem_Info] PRIMARY KEY CLUSTERED
(
[DGItemSID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
Why would deleting 2 rows using IN() on a child table create a hash match of 197 million rows, this query times out in the app, but deleting 1 row using = or IN() works fine and completes instantly?
Exec plans and queries:
DELETE FROM dbo.ClientDepartmentContact WHERE ClientDepartmentContactId IN (12126,12127)
https://www.brentozar.com/pastetheplan/?id=rkKueM6HS
DELETE FROM dbo.ClientDepartmentContact WHERE ClientDepartmentContactId = 12126
https://www.brentozar.com/pastetheplan/?id=Sku2lGaBr
The primary/foreign keys relationship are not set to to cascade.
DDLs:
CREATE TABLE [dbo].[ClientDepartmentContact](
[ClientDepartmentContactId] [int] IDENTITY(1,1) NOT NULL,
[ClientId] [int] NOT NULL,
[DepartmentId] [smallint] NOT NULL,
[DispatchContactId] [int] NOT NULL,
[DispatchType] [char](1) NOT NULL,
[DispatchContactType] [char](1) NOT NULL,
CONSTRAINT [PK_ClientDepartmentContact] PRIMARY KEY CLUSTERED
(
[ClientDepartmentContactId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
CONSTRAINT [UK_ClientDepartmentContact] UNIQUE NONCLUSTERED
(
[ClientId] ASC,
[DepartmentId] ASC,
[DispatchContactId] ASC,
[DispatchType] ASC,
[DispatchContactType] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
--Index
ALTER TABLE [dbo].[ClientDepartmentContact] ADD CONSTRAINT [PK_ClientDepartmentContact] PRIMARY KEY CLUSTERED
(
[ClientDepartmentContactId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
ALTER TABLE [dbo].[ClientDepartmentContact] ADD CONSTRAINT [UK_ClientDepartmentContact] UNIQUE NONCLUSTERED
(
[ClientId] ASC,
[DepartmentId] ASC,
[DispatchContactId] ASC,
[DispatchType] ASC,
[DispatchContactType] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
CREATE TABLE [dbo].[ClientDepartmentContact](
[ClientDepartmentContactId] [int] IDENTITY(1,1) NOT NULL,
[ClientId] [int] NOT NULL,
[DepartmentId] [smallint] NOT NULL,
[DispatchContactId] [int] NOT NULL,
[DispatchType] [char](1) NOT NULL,
[DispatchContactType] [char](1) NOT NULL,
CONSTRAINT [PK_ClientDepartmentContact] PRIMARY KEY CLUSTERED
(
[ClientDepartmentContactId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
CONSTRAINT [UK_ClientDepartmentContact] UNIQUE NONCLUSTERED
(
[ClientId] ASC,
[DepartmentId] ASC,
[DispatchContactId] ASC,
[DispatchType] ASC,
[DispatchContactType] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
--Index
ALTER TABLE [dbo].[ClientDepartmentContact] ADD CONSTRAINT [PK_ClientDepartmentContact] PRIMARY KEY CLUSTERED
(
[ClientDepartmentContactId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
ALTER TABLE [dbo].[ClientDepartmentContact] ADD CONSTRAINT [UK_ClientDepartmentContact] UNIQUE NONCLUSTERED
(
[ClientId] ASC,
[DepartmentId] ASC,
[DispatchContactId] ASC,
[DispatchType] ASC,
[DispatchContactType] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
CREATE TABLE [dbo].[DispatchContact](
[DispatchContactId] [int] IDENTITY(1,1) NOT NULL,
[Email] [varchar](254) NOT NULL,
CONSTRAINT [PK_DispatchContact] PRIMARY KEY CLUSTERED
(
[DispatchContactId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE UNIQUE NONCLUSTERED INDEX [IX_ContactAddress_Email] ON [dbo].[DispatchContact]
(
[Email] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
ALTER TABLE [dbo].[DispatchContact] ADD CONSTRAINT [PK_DispatchContact] PRIMARY KEY CLUSTERED
(
[DispatchContactId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SQL version 2012 standard, all stats are up to date.
Before asking for help, i have restored to the DB to a 2014 and 2017 (both standard) dev instance and cant recreate the exec plan, the queries exec instantly on those. The plan for the 2017 is:
https://www.brentozar.com/pastetheplan/?id=BJdpX76rH
Stats are updated via a maintenance job nightly, but I did update all stats while investigating the issue. I have tried adding index's using SentryOnes Plan explorer Index analysis tool to no avail.
ps Thanks for your help
I have a table with 24 milion rows.
I want to run this query:
select r1.userID, r2.userID, sum(r1.rate * r2.rate) as sum
from dbo.Ratings as r1
join dbo.Ratings as r2
on r1.movieID = r2.movieID
where r1.userID <= r2.userID
group by r1.userID, r2.userID
As I tested, it took 24 hours to produce 0.02 percent of the final result.
How can I speed it up?
Here is the definition of the table:
CREATE TABLE [dbo].[Ratings](
[userID] [int] NOT NULL,
[movieID] [int] NOT NULL,
[rate] [real] NOT NULL,
PRIMARY KEY CLUSTERED
(
[userID] ASC,
[movieID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [IX_RatingsMovies] ON [dbo].[Ratings]
(
[movieID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [IX_RatingsUsers] ON [dbo].[Ratings]
(
[userID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
Here is the execution plan:
The workaround I suggested was to create a "reverse" index:
CREATE INDEX IX_Ratings_Reverse on Ratings(movieid, userid) include(rate);
and then force SQL Server to use it:
select r1.userID, r2.userID, sum(r1.rate * r2.rate) as sum
from dbo.Ratings as r1 join dbo.Ratings as r2
with (index(IX_Ratings_Reverse))
on r1.movieID = r2.movieID
where r1.userID <= r2.userID group by r1.userID, r2.userID
There are two things that might help.
1) Change the order of columns in your clustered index to MovieID,UserID. This would group all the same MovieID's together first, which might change your Hash Match to an Inner Loop, and improve the performance of the JOIN.
2) Change the [IX_RatingsMovies] index to INCLUDE UserID and Rate. The more I think about it, I think this is less likely than my first suggestion to help. But it's possible.
I have the following two tables (only relevant key columns shown)
CREATE TABLE [dbo].[Jobs](
[ID] [int] IDENTITY(1,1) NOT NULL,
[JobNo] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_Jobs] 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]
) ON [PRIMARY]
CREATE TABLE [dbo].[Items](
[JobID] [int] NOT NULL,
[BarcodeNo] [nvarchar](50) NOT NULL,
[SerialNo] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_Items_1] PRIMARY KEY CLUSTERED
(
[JobID] ASC,
[BarcodeNo] ASC,
[SerialNo] 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 need to make sure that when an item is entered, the JobID matches an ID in the Jobs table. It seems, I can't use a FK because the PK in the items table is a composite key of 3 columns.
TIA
Mark
What kind of constraint can I use for this?
A foreign key works fine.
There's no problem with having the single column [dbo].[Items].[JobID] reference the PK of jobs.
CREATE TABLE [dbo].[Jobs]
(
[ID] [INT] IDENTITY(1, 1) NOT NULL,
[JobNo] [NVARCHAR](50) NOT NULL,
CONSTRAINT [PK_Jobs] 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]
)
ON [PRIMARY]
CREATE TABLE [dbo].[Items]
(
[JobID] [INT] NOT NULL REFERENCES [dbo].[Jobs]([ID]), /*<-- FK declaration*/
[BarcodeNo] [NVARCHAR](50) NOT NULL,
[SerialNo] [NVARCHAR](50) NOT NULL,
CONSTRAINT [PK_Items_1] PRIMARY KEY CLUSTERED ( [JobID] ASC, [BarcodeNo] ASC, [SerialNo] ASC )
WITH (PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
)
ON [PRIMARY]
EDIT:
We're in the process of moving server and I've just tested this on the new server. There's no performance problem there. This seems to be down to an underpowered, badly organised server.
One of our processes suddenly ran very slowly last night. The slow step was tracked down to an update statement on a table that was admittedly not too cleverly indexed.
So today I've added indexes to all the tables involved, but I'm still getting terrible performance.
I really don't understand it - possibly I'm still doing something less than smart.
Any suggestions welcomed.
update is as follows:
update test_HDM_RTT
set patient_district_no = b.legacy_number
from test_HDM_RTT a
inner join PHD.migration.PatScope b
on a.patient_pas_no = b.TrustNumber
patscope is 2474147 rows, test_hdm_rtt is 815278
definition of tables:
CREATE TABLE [dbo].[test_HDM_RTT](
[pk_episode_id] [int] NULL,
[pk_event_id] [int] NOT NULL,
[activity_date] [datetime] NULL,
[activity_datetime] [datetime] NULL,
[activity_subtype1] [nvarchar](50) NULL,
[activity_subtype1_code] [nvarchar](50) NULL,
[activity_subtype2] [nvarchar](50) NULL,
[activity_subtype2_code] [nvarchar](50) NULL,
[activity_type] [nvarchar](50) NULL,
[activity_type_code] [nvarchar](50) NULL,
[clock_start_date] [datetime] NULL,
[clock_stop_date] [datetime] NULL,
[dir_code] [nvarchar](10) NULL,
[div_code] [nvarchar](10) NULL,
[episode_id_ext] [nvarchar](50) NULL,
[episode_id_appt] [nvarchar](50) NULL,
[episode_id_ref] [nvarchar](50) NULL,
[episode_id_ref_medway] [nvarchar](50) NULL,
[episode_id_wl] [nvarchar](50) NULL,
[erod] [datetime] NULL,
[nhs_number] [nvarchar](20) NULL,
[patient_id] [int] NULL,
[patient_district_no] [nvarchar](20) NULL,
[patient_pas_no] [nvarchar](50) NULL,
[pathway_id] [nvarchar](50) NULL,
[pct_code] [nvarchar](10) NULL,
[ref_source_code] [nvarchar](10) NULL,
[rtt_episode_id] [nvarchar](50) NULL,
[rtt_outcome_code] [nvarchar](50) NULL,
[rtt_outcome_desc] [nvarchar](50) NULL,
[rtt_start_date] [datetime] NULL,
[rtt_start_ind] [nvarchar](10) NULL,
[rtt_stop_date] [datetime] NULL,
[site_code] [nvarchar](10) NULL,
[spec_natcode] [nvarchar](10) NULL,
[spec_pascode] [nvarchar](10) NULL,
[transfer_text] [nvarchar](100) NULL,
[op_rtt_count] [int] NULL,
[app_rec_date] [datetime] NULL,
[cons_code] [varchar](10) NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
USE [PIP]
/****** Object: Index [pk_event_id_clustered] Script Date: 03/06/2013 14:46:52 ******/
CREATE CLUSTERED INDEX [pk_event_id_clustered] ON [dbo].[test_HDM_RTT]
(
[pk_event_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
USE [PIP]
/****** Object: Index [idx_episode_id_appt] Script Date: 03/06/2013 14:46:52 ******/
CREATE NONCLUSTERED INDEX [idx_episode_id_appt] ON [dbo].[test_HDM_RTT]
(
[episode_id_appt] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
USE [PIP]
/****** Object: Index [idx_episode_id_ref] Script Date: 03/06/2013 14:46:52 ******/
CREATE NONCLUSTERED INDEX [idx_episode_id_ref] ON [dbo].[test_HDM_RTT]
(
[episode_id_ref] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
USE [PIP]
/****** Object: Index [idx_episode_id_wl] Script Date: 03/06/2013 14:46:52 ******/
CREATE NONCLUSTERED INDEX [idx_episode_id_wl] ON [dbo].[test_HDM_RTT]
(
[episode_id_wl] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
USE [PIP]
/****** Object: Index [patient_pas_no] Script Date: 03/06/2013 14:46:52 ******/
CREATE NONCLUSTERED INDEX [patient_pas_no] ON [dbo].[test_HDM_RTT]
(
[patient_pas_no] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
and
USE [PHD]
GO
/****** Object: Table [migration].[PatScope] Script Date: 03/06/2013 14:47:57 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [migration].[PatScope](
[RID] [varchar](7) NOT NULL,
[Number] [varchar](17) NOT NULL,
[TrustNumber] [varchar](10) NULL,
[NumberType] [nvarchar](10) NULL,
[legacy_number] [varchar](10) NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
USE [PHD]
/****** Object: Index [TrustNoClustered] Script Date: 03/06/2013 14:47:57 ******/
CREATE CLUSTERED INDEX [TrustNoClustered] ON [migration].[PatScope]
(
[TrustNumber] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
USE [PHD]
/****** Object: Index [TrustNo] Script Date: 03/06/2013 14:47:57 ******/
CREATE NONCLUSTERED INDEX [TrustNo] ON [migration].[PatScope]
(
[TrustNumber] ASC,
[Number] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
USE [PHD]
/****** Object: Index [TrustNumber_legacy_lookup] Script Date: 03/06/2013 14:47:57 ******/
CREATE UNIQUE NONCLUSTERED INDEX [TrustNumber_legacy_lookup] ON [migration].[PatScope]
(
[TrustNumber] ASC,
[legacy_number] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
personally, I would only update if the value is not the same as existing. That should speed up the query
update test_HDM_RTT
set patient_district_no = b.legacy_number
from test_HDM_RTT a
inner join PHD.migration.PatScope b
on a.patient_pas_no = b.TrustNumber
where a.patient_district_no <> b.legacy_number
I would also check out the EXPLAIN results (ctrl + l) your query may be using the wrong index.
Show Execution Plan & see if the plan uses indexes. If it doesn't, you can force it to use a particular index:
SET ANSI_NULLS OFF
GO
update test_HDM_RTT
set patient_district_no = b.legacy_number
from test_HDM_RTT a
inner join PHD.migration.PatScope b WITH (INDEX(TrustNumber_legacy_lookup))
on a.patient_pas_no = b.TrustNumber
where a.patient_district_no <> b.legacy_number
You'll want to see if you need to force an index on test_HDM_RTT instead because it looks like it's already going to do an index scan of TrustNumber_legacy_lookup to get its data.