【问题标题】:Very Slow Update despite Indexing MSSQL 2005尽管索引 MSSQL 2005,但更新速度非常慢
【发布时间】:2013-02-21 10:24:03
【问题描述】:

编辑: 我们正在移动服务器,我刚刚在新服务器上进行了测试。那里没有性能问题。这似乎归结为一个动力不足、组织不善的服务器。

昨晚我们的一个进程突然运行得很慢。缓慢的步骤被追踪到一个表上的更新语句,该表被承认不是太聪明地索引。

所以今天我已经为所有涉及的表添加了索引,但我的性能仍然很糟糕。 我真的不明白——可能我还在做一些不太聪明的事情。 欢迎提出任何建议。

更新如下:

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 为 2474147 行,test_hdm_rtt 为 815278

表格定义:

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

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

【问题讨论】:

  • 查看查询计划。它是否使用您期望的索引?检查碎片。即使您确定值不一样,我仍然会按照马特的建议执行 。而且我没有在 a.patient_pas_no 上看到索引。
  • @Blam a.patient_pas_no 上的索引位于第一个代码块的最底部。一开始我也错过了。
  • @MattBusche 你是对的
  • patient_pas_no 的索引在那里,但隐藏在底部!
  • 嘿 :) 为其他建议干杯。我会尝试 - 我排除了这个,因为我认为它会减慢速度,因为我们希望找到的每一行都更新 - 你知道为什么这可能会改善事情吗?我在查询计划中没有发现任何明显的东西,但我应该多加注意。我正在等待查询运行并再次启动 hte 计划,我会看看有什么要说的。谢谢

标签: sql-server tsql sql-server-2005 indexing


【解决方案1】:

就个人而言,我只会在值与现有值不同时更新。这应该会加快查询速度

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

我还会查看EXPLAIN 结果 (ctrl + l),您的查询可能使用了错误的索引。

【讨论】:

  • 谢谢,我同意 - 我通常也会。在这种情况下,虽然我们可以肯定地知道,如果在 patscope 中找到了一个值,它就不会与表中的值相同。
  • where a.patient_district_no &lt;&gt; b.legacy_number 的问题是你会错过NULL 的值 - 涉及NULL 的比较返回NULL,除非你在执行更新之前已经SET ANSI_NULLS OFF。跨度>
【解决方案2】:

显示执行计划并查看该计划是否使用索引。如果没有,您可以强制它使用特定索引:

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

您需要查看是否需要强制在 test_HDM_RTT 上建立索引,因为它看起来已经准备对 TrustNumber_legacy_lookup 进行索引扫描以获取其数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-15
    • 1970-01-01
    • 2012-04-01
    • 2016-03-12
    • 1970-01-01
    • 1970-01-01
    • 2021-09-27
    相关资源
    最近更新 更多