Int / Smallint가 Varchar로 암시 적으로 변환되는 이유는 무엇이며 카디널리티 예상치에 실제로 영향을 미칩니 까?


11

실제 실행 계획에서 SSMS (Show Plan Analysis)를 사용하여 성능이 느린 쿼리를 작성하는 데 문제가 있습니다. 분석 도구는 계획의 일부 위치에서 반환 된 결과에서 행 수에 대한 추정치가 벗어나고 암시 적 변환 경고를 제공한다고 지적합니다.

나는 int를 Varchar로 암시 적으로 변환하는 것을 이해하지 못합니다. 참조 된 필드는 쿼리의 매개 변수 / 필터의 일부가 아니며 관련된 모든 테이블에서 열 데이터 유형이 동일합니다.

다음과 같은 카디널리티 예상 경고가 나타납니다.

식의 형식 변환 (CONVERT_IMPLICIT (varchar (12), [ccd]. [profileid], 0))이 쿼리 계획 선택의 "CardinalityEstimate"에 영향을 줄 수 있음-이 필드는 내 DB의 모든 위치에있는 정수입니다.

식의 형식 변환 (CONVERT_IMPLICIT (varchar (6), [ccd]. [nodeid], 0))이 쿼리 계획 선택의 "CardinalityEstimate"에 영향을 줄 수 있음-이 필드는 내 DB의 모든 곳에서 가장 작은 부분입니다

식의 형식 변환 (CONVERT_IMPLICIT (varchar (6), [ccd]. [sessionseqnum], 0))이 쿼리 계획 선택의 "CardinalityEstimate"에 영향을 줄 수 있음-이 필드는 내 DB의 모든 곳에서 smallint입니다

식 (CONVERT_IMPLICIT (varchar (41), [ccd]. [sessionid], 0))의 형식 변환은 쿼리 계획 선택의 "CardinalityEstimate"에 영향을 줄 수 있습니다.이 필드는 내 DB의 모든 곳에서 10 진수입니다.

[편집] 다음은 참조 용 쿼리 및 실제 실행 계획입니다. https://www.brentozar.com/pastetheplan/?id=SysYt0NzN

그리고 테이블 정의 ..

/****** Object:  Table [dbo].[agentconnectiondetail]    Script Date: 1/10/2019 9:10:04 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[agentconnectiondetail](
    [sessionid] [decimal](18, 0) NOT NULL,
    [sessionseqnum] [smallint] NOT NULL,
    [nodeid] [smallint] NOT NULL,
    [profileid] [int] NOT NULL,
    [resourceid] [int] NOT NULL,
    [startdatetime] [datetime2](7) NOT NULL,
    [enddatetime] [datetime2](7) NOT NULL,
    [qindex] [smallint] NOT NULL,
    [gmtoffset] [smallint] NOT NULL,
    [ringtime] [smallint] NULL,
    [talktime] [smallint] NULL,
    [holdtime] [smallint] NULL,
    [worktime] [smallint] NULL,
    [callwrapupdata] [varchar](40) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [callresult] [smallint] NULL,
    [dialinglistid] [int] NULL,
    [convertedStartDatetimelocal] [datetime2](7) NULL,
    [convertedEndDatetimelocal] [datetime2](7) NULL,
 CONSTRAINT [PK_agentconnectiondetail] PRIMARY KEY CLUSTERED 
(
    [sessionid] ASC,
    [sessionseqnum] ASC,
    [nodeid] ASC,
    [profileid] ASC,
    [resourceid] ASC,
    [startdatetime] ASC,
    [qindex] 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
/****** Object:  Table [dbo].[contactcalldetail]    Script Date: 1/10/2019 9:10:04 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[contactcalldetail](
    [sessionid] [decimal](18, 0) NOT NULL,
    [sessionseqnum] [smallint] NOT NULL,
    [nodeid] [smallint] NOT NULL,
    [profileid] [int] NOT NULL,
    [contacttype] [smallint] NOT NULL,
    [contactTypeDescription] [varchar](20) COLLATE Latin1_General_CI_AS NULL,
    [contactdisposition] [smallint] NOT NULL,
    [contactdispositionDescription] [varchar](20) COLLATE Latin1_General_CI_AS NULL,
    [dispositionreason] [varchar](100) COLLATE Latin1_General_CI_AS NULL,
    [originatortype] [smallint] NOT NULL,
    [originatorTypeDescription] [varchar](20) COLLATE Latin1_General_CI_AS NULL,
    [originatorid] [int] NULL,
    [originatordn] [varchar](30) COLLATE Latin1_General_CI_AS NULL,
    [destinationtype] [smallint] NULL,
    [destinationTypeDescription] [varchar](20) COLLATE Latin1_General_CI_AS NULL,
    [destinationid] [int] NULL,
    [destinationdn] [varchar](30) COLLATE Latin1_General_CI_AS NULL,
    [startdatetimeUTC] [datetime2](7) NOT NULL,
    [enddatetimeUTC] [datetime2](7) NOT NULL,
    [gmtoffset] [smallint] NOT NULL,
    [callednumber] [varchar](30) COLLATE Latin1_General_CI_AS NULL,
    [origcallednumber] [varchar](30) COLLATE Latin1_General_CI_AS NULL,
    [applicationtaskid] [decimal](18, 0) NULL,
    [applicationid] [int] NULL,
    [applicationname] [varchar](30) COLLATE Latin1_General_CI_AS NULL,
    [connecttime] [smallint] NULL,
    [customvariable1] [varchar](40) COLLATE Latin1_General_CI_AS NULL,
    [customvariable2] [varchar](40) COLLATE Latin1_General_CI_AS NULL,
    [customvariable3] [varchar](40) COLLATE Latin1_General_CI_AS NULL,
    [customvariable4] [varchar](40) COLLATE Latin1_General_CI_AS NULL,
    [customvariable5] [varchar](40) COLLATE Latin1_General_CI_AS NULL,
    [customvariable6] [varchar](40) COLLATE Latin1_General_CI_AS NULL,
    [customvariable7] [varchar](40) COLLATE Latin1_General_CI_AS NULL,
    [customvariable8] [varchar](40) COLLATE Latin1_General_CI_AS NULL,
    [customvariable9] [varchar](40) COLLATE Latin1_General_CI_AS NULL,
    [customvariable10] [varchar](40) COLLATE Latin1_General_CI_AS NULL,
    [accountnumber] [varchar](40) COLLATE Latin1_General_CI_AS NULL,
    [callerentereddigits] [varchar](40) COLLATE Latin1_General_CI_AS NULL,
    [badcalltag] [char](1) COLLATE Latin1_General_CI_AS NULL,
    [transfer] [bit] NULL,
    [NextSeqNum] [smallint] NULL,
    [redirect] [bit] NULL,
    [conference] [bit] NULL,
    [flowout] [bit] NULL,
    [metservicelevel] [bit] NULL,
    [campaignid] [int] NULL,
    [origprotocolcallref] [varchar](32) COLLATE Latin1_General_CI_AS NULL,
    [destprotocolcallref] [varchar](32) COLLATE Latin1_General_CI_AS NULL,
    [convertedStartDatetimelocal] [datetime2](7) NULL,
    [convertedEndDatetimelocal] [datetime2](7) NULL,
    [AltKey]  AS (concat([sessionid],[sessionseqnum],[nodeid],[profileid]) collate database_default) PERSISTED NOT NULL,
    [PrvSeqNum] [smallint] NULL,
 CONSTRAINT [PK_contactcalldetail] PRIMARY KEY CLUSTERED 
(
    [sessionid] ASC,
    [sessionseqnum] ASC,
    [nodeid] ASC,
    [profileid] 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
/****** Object:  Table [dbo].[contactqueuedetail]    Script Date: 1/10/2019 9:10:04 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[contactqueuedetail](
    [sessionid] [decimal](18, 0) NOT NULL,
    [sessionseqnum] [smallint] NOT NULL,
    [profileid] [int] NOT NULL,
    [nodeid] [smallint] NOT NULL,
    [targetid] [int] NOT NULL,
    [targettype] [smallint] NOT NULL,
    [targetTypeDescription] [varchar](10) COLLATE Latin1_General_CI_AS NULL,
    [qindex] [smallint] NOT NULL,
    [queueorder] [smallint] NOT NULL,
    [disposition] [smallint] NULL,
    [dispositionDescription] [varchar](50) COLLATE Latin1_General_CI_AS NULL,
    [metservicelevel] [bit] NULL,
    [queuetime] [smallint] NULL,
 CONSTRAINT [PK_contactqueuedetail] PRIMARY KEY CLUSTERED 
(
    [sessionid] ASC,
    [sessionseqnum] ASC,
    [profileid] ASC,
    [nodeid] ASC,
    [targetid] ASC,
    [targettype] ASC,
    [qindex] 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
/****** Object:  Index [<Name of Missing Index, sysname,>]    Script Date: 1/10/2019 9:10:04 AM ******/
CREATE NONCLUSTERED INDEX [<Name of Missing Index, sysname,>] ON [dbo].[contactcalldetail]
(
    [convertedStartDatetimelocal] ASC
)
INCLUDE (   [sessionid],
    [sessionseqnum],
    [nodeid],
    [profileid]) 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
/****** Object:  Index [idx_CCD_ContactType_DestType_StDtLocal]    Script Date: 1/10/2019 9:10:04 AM ******/
CREATE NONCLUSTERED INDEX [idx_CCD_ContactType_DestType_StDtLocal] ON [dbo].[contactcalldetail]
(
    [destinationtype] ASC,
    [contacttype] ASC,
    [convertedStartDatetimelocal] ASC
)
INCLUDE (   [sessionid],
    [sessionseqnum],
    [nodeid],
    [profileid],
    [convertedEndDatetimelocal]) 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
/****** Object:  Index [idx_CQD_Profile_Traget_TargetType]    Script Date: 1/10/2019 9:10:04 AM ******/
CREATE NONCLUSTERED INDEX [idx_CQD_Profile_Traget_TargetType] ON [dbo].[contactqueuedetail]
(
    [profileid] ASC,
    [targetid] ASC,
    [targettype] ASC
)
INCLUDE (   [targetTypeDescription],
    [queueorder],
    [disposition],
    [dispositionDescription],
    [queuetime]) 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

답변:


11

내재적 변환은 계산 열에 의해 발생합니다 AltKey.

CREATE TABLE dbo.Test
(
    [sessionid] [decimal](18, 0) NOT NULL,
    [sessionseqnum] [smallint] NOT NULL,
    [nodeid] [smallint] NOT NULL,
    [profileid] [int] NOT NULL,
    [AltKey] AS 
        CONCAT
        (
            [sessionid],
            [sessionseqnum],
            [nodeid],
            [profileid]
        ) PERSISTED NOT NULL,
);

위의 단순화 된 표가 주어지면 아래의 간단한 설명은 질문에 제공된 것과 동일한 암시 적 변환 경고를 생성합니다.

SELECT T.*
FROM dbo.Test AS T;

경고 계획

에서 문서 (강조는 추가) :

CONCAT 연결하기 전에 모든 인수를 문자열 유형으로 암시 적으로 변환 합니다.

SQL Server가 지속 형 값을 사용하지 않고 명시 적으로 값을 계산하는 계획 대안을 고려할 때 경고가 추가됩니다. 최종 계획이 지속 된 값을 사용하면 경고가 제거되지 않습니다.

이 경우 경고는 무시해도됩니다. 이것은 내가 알 수있는 한 실행 계획에도 적용됩니다. 관련 암시 적 변환 CONCAT은 계획 선택에 부정적인 영향을 미치지 않습니다.

사용 미등록 지원되지 않는 176 개 방지가 계산 된 열 팽창을 유지하고, 경고를 제거 추적 플래그 :

SELECT * 
FROM dbo.Test AS T
OPTION (QUERYTRACEON 176);

tf 176로

자세한 내용은 내 기사 적절하게 계산 된 계산 열 을 참조하십시오.


5

다음은 암시 적 변환 경고가 표시되는 필드입니다.

  • [ccd].[profileid] (varchar (12)와 동일)
  • [ccd].[nodeid] (작은 varchar (6))
  • [ccd].[sessionseqnum] (작은 varchar (6))
  • [ccd].[sessionid] (varchar (41)에 10 진수)

참조 된 필드는 쿼리에서 매개 변수 / 필터의 일부가 아닙니다.

그들이 당신의 가입 조건에 있는지 확인하십시오. ccd.profileid가 필터로 사용되는 곳 (및 에이전트 연결 세부 사항에 대한 결합)은 다음과 같습니다.

FROM contactcalldetail ccd 
    INNER JOIN contactqueuedetail csqd 
        ON ccd.sessionID=csqd.sessionid 
            AND ccd.sessionSeqNum=csqd.sessionSeqNum 
            AND ccd.nodeID=csqd.nodeID 
            AND ccd.profileid=csqd.profileid -- Right here

관련된 모든 테이블에서 열 데이터 유형은 동일합니다.

테이블 정의를 다시 확인하십시오.

  • contactcalldetail.profileid
  • contactqueuedetail.profileid
  • agentconnectiondetail .profileid

그들이 사용하고 있다고 생각하는 데이터 유형을 사용하지 않는 것 같습니다.

카디널리티 예상치에 실제로 영향을 미칩니 까?

귀하가 제공 한 정보에 근거하여 제 답변에 약간의 추측이 진행되고 있습니다. 실제 실행 계획 및 테이블 정의를 질문에 추가하여 이러한 암시 적 변환 문제에 영향을 줄 수있는 모든 세부 정보를 얻을 수 있습니다.

일반적으로 조인 조건에 대한 암시 적 변환은 추정에 심각한 문제를 일으킬 수 있습니다 . 실제 실행 계획을 보지 않고 귀하의 경우에 이것이 일어나고 있는지 말하기는 어렵습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.