簡體   English   中英

在SQL Server上運行非常慢的Insert語句

[英]Insert statement running very slowly on SQL Server

我一直在從生產中獲取數據並將其加載到暫存DWH中。 然后,通過分階段在另一個DWH中將其進一步加載為可用格式。

登台和最終DWH都在同一服務器上。 這個過程並不需要很長時間,但是現在要花費很多時間才能從暫存中加載數據。 將生產中的數據加載到暫存中需要花費幾分鍾,但是進一步加載它需要花費數小時,我不確定為什么。

僅供參考:我一直在測試負載,所以我幾次將表截斷/刪除並重新加載

我在刪除的實際DWH的其中一列上也有一個非聚集索引

CONSTRAINT [PK_EncounterTB_Encounter_id] 
    PRIMARY KEY CLUSTERED ([Encounter_id] ASC),
CONSTRAINT [Uniq_EncounterTB_Encounter_table_id] 
    UNIQUE NONCLUSTERED ([Encounter_Table_id] ASC)

下面是分期的表結構,我刪除了一些列:

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Stg_Encounter]
(
    [encntr_id] [float] NOT NULL,
    [person_id] [float] NOT NULL,
    [visit_id_stay_number] [varchar](1000) NULL,
    [mrn] [varchar](1000) NULL,
    [encntr_type_cd] [float] NULL,
    [reg_dt_tm] [datetime2](7) NULL,
    [disch_dt_tm] [datetime2](7) NULL,
    [admit_cd] [float] NULL,
    [visit_cd] [float] NULL,
    [source_cd] [float] NULL,
    [sepearation_cd] [float] NULL,
    [medical_service_cd] [float] NULL,
    [reason_problem] [varchar](1000) NULL,
) ON [PRIMARY]
GO

對於實際的DWH,表結構如下:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Encounter]
(
    [Encounter_Table_id] [int] NOT NULL,
    [Encounter_id] [int] NOT NULL,
    [Person_id] [int] NOT NULL,
    [Visit_ID] [varchar](1000) NULL,
    [MRN] [varchar](1000) NULL,
    [Encounter_Type] [varchar](1000) NULL,
    [Arrival_Dt_Tm] [datetime2](7) NULL,
    [Departure_Dt_Tm] [datetime2](7) NULL,
    [Mode_of_Arrival] [varchar](1000) NULL,
    [Visit_Type] [varchar](1000) NULL,
    [Admit_Source] [varchar](1000) NULL,
    [Mode_of_Separation] [varchar](1000) NULL,
    [Medical_Service] [varchar](1000) NULL,
    [Presenting_Problem] [varchar](1000) NULL,
    [LOAD_Dt_Tm] [datetime] NOT NULL,
    [Data_Source] [varchar](1000) NOT NULL,

    CONSTRAINT [PK_EncounterTB_Encounter_id] 
        PRIMARY KEY CLUSTERED ([Encounter_id] ASC)
) ON [PRIMARY]
GO

下面的insert用於插入數據:

INSERT INTO [ACTUAL_DWH].[dbo].[Encounter] 
        (
[Encounter_Table_id]
  ,[Encounter_id]
  ,[Person_id]
  ,[Visit_ID]
  ,[MRN]
  ,[Encounter_Type]
  ,[Arrival_Dt_Tm]
  ,[Departure_Dt_Tm]
  ,[Mode_of_Arrival]
  ,[Visit_Type]
  ,[Admit_Source]
  ,[Mode_of_Separation]
  ,[Medical_Service]
  ,[Presenting_Problem]
  ,[MSAU_LOAD_Dt_Tm]
  ,[Data_Source]    
    )
SELECT
[Encounter_Table_id]= CONVERT(INT,Stg_e.[encntr_id])
    ,   [Encounter_id]                      = CONVERT(INT,Stg_e.[encntr_id])
  ,[Person_id]                          = CONVERT(INT,Stg_e.[person_id])
  ,[Visit_ID]                           = Stg_e.[visit_id_stay_number]
  ,[MRN]                                = Stg_e.[mrn]
  ,[Encounter_Type]                     = [ACTUAL_DWH].[dbo].[emr_get_code_Description](Stg_e.encntr_type_cd)
  ,[Arrival_Dt_Tm]                      = CONVERT(DATETIME,Stg_e.reg_dt_tm)
  ,[Departure_Dt_Tm]                    = CONVERT(DATETIME,Stg_e.disch_dt_tm)
  ,[Mode_of_Arrival]                    = [ACTUAL_DWH].[dbo].[Description](Stg_e.admit_cd)
  ,[Visit_Type]                         = [ACTUAL_DWH].[dbo].[Description](Stg_e.visit_cd)
  ,[Admit_Source]                       = [ACTUAL_DWH].[dbo].[Description](Stg_e.source_cd)
  ,[Mode_of_Separation]                 = [ACTUAL_DWH].[dbo].[Description](Stg_e.sepearation_cd)
  ,[Medical_Service]                    = [ACTUAL_DWH].[dbo].[Description](Stg_e.medical_service_cd)
  ,[Presenting_Problem]                 = Stg_e.reason_problem
  ,[MSAU_LOAD_Dt_Tm]                    = getdate()
  ,[Data_Source]                        = 'SourceName'



    FROM [dbo].Stg_Encounter Stg_e
    where NOT EXISTS ( SELECT 1 FROM [ACTUAL_DWH].[dbo].Encounter e
                            WHERE stg_e.encntr_id = e.encounter_id)

使用的功能如下:

USE [ACTUAL_DWH]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER function [dbo].[Description](@cv int)  
returns varchar(80)  
as begin   

declare @ret varchar(80)  
select @ret = cv.DESCRIPTION
from ACTUAL_DWH.DBO.CODE_VALUE cv   
where cv.code_value = @cv   
    and cv.active_ind = 1  
return isnull(@ret, 0)

end;

我只是在錯過東西的地方感到困惑!!! 而我可以改變。 該表大約有600萬行,並且在一分鍾之內就已加載完畢。

在提供了建議之后,我知道了我所使用的功能存在問題。我已經閱讀了有關CROSS APPLY的知識,但是將CROSS APPLY應用於15列是個好主意嗎?

您可以使用SQL CREATE INDEX語句非常快地從數據庫中檢索數據。

    CREATE INDEX IX_Encounter
            ON [ACTUAL_DWH].[dbo].[Encounter](Encounter_Table_id) ON [PRIMARY]

    INSERT INTO [ACTUAL_DWH].[dbo].[Encounter] 
            (
    [Encounter_Table_id]
      ,[Encounter_id]
      ,[Person_id]
      ,[Visit_ID]
      ,[MRN]
      ,[Encounter_Type]
      ,[Arrival_Dt_Tm]
      ,[Departure_Dt_Tm]
      ,[Mode_of_Arrival]
      ,[Visit_Type]
      ,[Admit_Source]
      ,[Mode_of_Separation]
      ,[Medical_Service]
      ,[Presenting_Problem]
      ,[MSAU_LOAD_Dt_Tm]
      ,[Data_Source]    
        )
    SELECT
    [Encounter_Table_id]= CONVERT(INT,Stg_e.[encntr_id])
        ,   [Encounter_id]                      = CONVERT(INT,Stg_e.[encntr_id])
      ,[Person_id]                          = CONVERT(INT,Stg_e.[person_id])
      ,[Visit_ID]                           = Stg_e.[visit_id_stay_number]
      ,[MRN]                                = Stg_e.[mrn]
      ,[Encounter_Type]                     = [ACTUAL_DWH].[dbo].[emr_get_code_Description](Stg_e.encntr_type_cd)
      ,[Arrival_Dt_Tm]                      = CONVERT(DATETIME,Stg_e.reg_dt_tm)
      ,[Departure_Dt_Tm]                    = CONVERT(DATETIME,Stg_e.disch_dt_tm)
      ,[Mode_of_Arrival]                    = [ACTUAL_DWH].[dbo].[Description](Stg_e.admit_cd)
      ,[Visit_Type]                         = [ACTUAL_DWH].[dbo].[Description](Stg_e.visit_cd)
      ,[Admit_Source]                       = [ACTUAL_DWH].[dbo].[Description](Stg_e.source_cd)
      ,[Mode_of_Separation]                 = [ACTUAL_DWH].[dbo].[Description](Stg_e.sepearation_cd)
      ,[Medical_Service]                    = [ACTUAL_DWH].[dbo].[Description](Stg_e.medical_service_cd)
      ,[Presenting_Problem]                 = Stg_e.reason_problem
      ,[MSAU_LOAD_Dt_Tm]                    = getdate()
      ,[Data_Source]                        = 'SourceName'



        FROM [dbo].Stg_Encounter Stg_e
        where NOT EXISTS ( SELECT 1 FROM [ACTUAL_DWH].[dbo].Encounter e
                                WHERE stg_e.encntr_id = e.encounter_id)

您可以在此處查看有關索引的更多信息。 指數

只是為了關閉這篇文章。 正如建議的那樣,我試圖分解查詢,發現該功能是罪魁禍首。 我正在進一步探索該決議。

該函數采用參數並在另一個表上運行SQL。 這減慢了查詢速度。 如果我執行不帶該功能的插入操作,則實際上需要幾秒鍾來加載600萬行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM