更新声明耗时太长(7分钟)

时间:2015-06-09 16:15:41

标签: sql sql-server sql-update execution-time sql-execution-plan

这是在SSMS 2008 R2上运行的SQL代码。它需要超过10分钟才能运行(它与90,000条记录相比)..

我正在尝试更新#tmp_hic_final中的所有唯一记录,其中[Claim Adjustment Type Code]为0且[Claim Type Code]不是10.我也在根据select子查询进行更新确保表中没有[声明调整类型代码]为1的其他记录。

虽然我对分析它并不了解,但这里是执行计划:http://snag.gy/TLRsZ.jpg

有更好的方法来优化它吗?

update  PAHT
set [Marked Final] = 'Y'
from #tmp_hic_final PAHT
join
(
    select [HIC #],
                [Claim Type Code] , 
                [Provider Oscar #], 
                [Claim From Date] ,
                 [Claim Thru Date]
    from #tmp_hic_final
    where [Claim Adjustment Type Code] = 0
    and [Claim Type Code] <> 10
    group by [HIC #],
                [Claim Type Code] , 
                [Provider Oscar #], 
                [Claim From Date] ,
                [Claim Thru Date] 
                --,[Claim Adjustment Type Code]
    having count(*) = 1
) as PAHT_2
on PAHT.[HIC #] = PAHT_2.[HIC #] and
                                        PAHT.[Claim Type Code] = PAHT_2.[Claim Type Code] and 
                                        PAHT.[Provider Oscar #] = PAHT_2.[Provider Oscar #] and
                                        PAHT.[Claim From Date] = PAHT_2.[Claim From Date]  and
                                        PAHT.[Claim Thru Date] = PAHT_2.[Claim Thru Date] 

where PAHT.[Claim Adjustment Type Code] = 0
and PAHT.[Claim Type Code] <> 10
and NOT EXISTS (select 
                    [Claim Adjustment Type Code] 
                from [ACO].[dbo].[PA_Header_Temp]
                where 
                    [HIC #] = PAHT.[HIC #]
                    and [Provider Oscar #] = PAHT.[Provider Oscar #]
                    and [Claim Type Code] = PAHT.[Claim Type Code]
                    and [Claim From Date] = PAHT.[Claim From Date]
                    and [Claim Thru Date] = PAHT.[Claim Thru Date]
                    and [Claim Adjustment Type Code]  = 1)

PA_Header_Temp上的表定义和索引:

/****** Object:  Table [dbo].['PA_Header']    Script Date: 06/02/2015 2:32:33 PM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO


CREATE TABLE [dbo].[PA_Header_Temp](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Current ClaimID] [float] NULL,
    [Provider OSCAR #] [nvarchar](255) NULL,
    [HIC #] [nvarchar](255) NULL,
    [Claim Type Code] [float] NULL,
    [Claim From Date] [datetime] NULL,
    [Claim Thru Date] [datetime] NULL,
    [Claim Bill Facility Type Code] [float] NULL,
    [Claim Bill Classification Code] [float] NULL,
    [Principal Diagnosis Code] [nvarchar](255) NULL,
    [Admitting Diagnosis Code] [nvarchar](255) NULL,
    [Claim Medicare Non Payment Reason Code] [nvarchar](255) NULL,
    [Claim Payment Amount] [float] NULL,
    [Claim NCH Primary Payer Code] [nvarchar](255) NULL,
    [FIPS state Code] [float] NULL,
    [Bene Patient Status Code] [float] NULL,
    [Diagnosis Related Group Code] [float] NULL,
    [Claim Outpatient Service Type Code] [nvarchar](255) NULL,
    [Facility Provider NPI #] [float] NULL,
    [Operating Provider NPI #] [nvarchar](255) NULL,
    [Attending provider NPI #] [float] NULL,
    [Other Provider NPI #] [nvarchar](255) NULL,
    [Claim Adjustment Type Code] [float] NULL,
    [Claim Effective Date] [datetime] NULL,
    [Claim IDR Load Date] [datetime] NULL,
    [Bene Equitable BIC HICN #] [nvarchar](255) NULL,
    [Claim Admission Type Code] [nvarchar](255) NULL,
    [Claim Admission Source Code] [nvarchar](255) NULL,
    [Claim Bill Frequency Code] [nvarchar](255) NULL,
    [Claim Query Code] [float] NULL,
    [Marked Final] [nvarchar](255) NULL,
    [Load Date] [datetime] NULL,
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]

GO

3 个答案:

答案 0 :(得分:2)

我从可读性和性能角度提出了这种方法。

update yourTable
set field2 = someValue
where whatever
and field1 in 
(select field1
from yourTable
where whatever
except
select field1
from yourTable
where whatever
and somethingElse)

where whatever每次都应该是相同的。

答案 1 :(得分:1)

我要检查的第一件事是表中的索引(正常和临时)。特别是嵌套循环中PA_Header_Temp的聚簇索引扫描看起来非常糟糕。根据列和数据(数据类型,选择性,行数),您应该使用部分或全部列创建索引,可以是普通字段,也可以是包含字段。

为temp创建聚簇索引可能是个好主意。表也​​可能在用于连接的列和#tmp_hic_final上,您还应该考虑用作更新中的条件的字段。

编辑:您是否尝试将PAHT_2填充到单独的临时值中。在运行更新之前的表(+索引它) - 这可能也有帮助。

答案 2 :(得分:0)

所以,我接受了@Dan Bracuk的建议并使用他的格式转换了我的代码,它将我的执行时间从6:57降低到2:30(如果我的数学是正确的,性能提高了65%)< / p>

update PAHT  
set PAHT.[Marked Final] = 'Y'
from #tmp_hic_final PAHT
where [Claim Adjustment Type Code] = 0
    and [Claim Type Code] <> 10
and [Claim Adjustment Type Code] in 
(select 
                    [Claim Adjustment Type Code] 
                from [ACO].[dbo].[PA_Header_Temp]
                where 
                    [HIC #] = PAHT.[HIC #]
                    and [Provider Oscar #] = PAHT.[Provider Oscar #]
                    and [Claim Type Code] = PAHT.[Claim Type Code]
                    and [Claim From Date] = PAHT.[Claim From Date]
                    and [Claim Thru Date] = PAHT.[Claim Thru Date]
except
select 
                    [Claim Adjustment Type Code] 
                from [ACO].[dbo].[PA_Header_Temp]
                where 
                    [HIC #] = PAHT.[HIC #]
                    and [Provider Oscar #] = PAHT.[Provider Oscar #]
                    and [Claim Type Code] = PAHT.[Claim Type Code]
                    and [Claim From Date] = PAHT.[Claim From Date]
                    and [Claim Thru Date] = PAHT.[Claim Thru Date]
                    and [Claim Adjustment Type Code]  = 1)