Оператор вставки работает очень медленно на SQL Server - PullRequest
0 голосов
/ 26 ноября 2018

Я получал данные с производства и загружал их в промежуточный 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 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;

Я просто запутался, когда япропустил вещи !!!И что я могу изменить.таблица содержит около 6 миллионов строк и загружает их за минуту.

После предоставленных предложений я узнал, что проблема связана с функцией, которую я использую. Я читал о CROSS APPLY, но стоит ли применять CROSS APPLY для 15 столбцов?

Ответы [ 2 ]

0 голосов
/ 30 ноября 2018

Просто чтобы закрыть этот пост.Как и предполагалось, я попытался разбить запрос и обнаружил, что функция была виновником.Я исследую его далее для разрешения.

Функция принимает параметр и запускает SQL для другой таблицы.Что замедляет запрос.Если я выполняю вставку без функции, на самом деле загрузка нескольких миллионов строк занимает несколько секунд.

0 голосов
/ 29 ноября 2018

Вы можете использовать оператор 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)

Более подробную информацию об индексе можно посмотреть здесь. INDEX

...