Why am I getting an implicit conversion of Int / Smallint to Varchar, and is it really impacting Cardinality Estimates?

The implicit conversions are caused by the computed column 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,
);

Given the above simplified table, the simple statement below generates the same implicit conversion warnings given in the question:

SELECT T.*
FROM dbo.Test AS T;

Plan with warnings

From the documentation (emphasis added):

CONCAT implicitly converts all arguments to string types before concatenation.

The warning is added when SQL Server considers a plan alternative that does not use the persisted value, but computes the value explicitly. The warning is not removed if the final plan uses the persisted value.

The warnings may be safely ignored in this case. This also applies to your execution plan, as far as I can tell - the implicit conversions involved in the CONCAT are not adversely affecting plan choice.

Using documented and supported trace flag 176 prevents persisted computed column expansion and removes the warnings:

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

with tf 176

See my article Properly Persisted Computed Columns for more details.


These are the fields you're getting implicit conversion warnings about:

  • [ccd].[profileid] (int to varchar(12))
  • [ccd].[nodeid] (smallint to varchar(6))
  • [ccd].[sessionseqnum] (smallint to varchar(6))
  • [ccd].[sessionid] (decimal to varchar(41))

The fields referenced are not part of any parameter/filter on the query

Sure they are, in your join conditions. Here is where ccd.profileid is being used as a filter (as well as in a join to agentconnectiondetail):

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

and in all tables involved the column data types are the same

You may want to double check the table definitions for

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

It sounds like they are not using the data types you think they are using.

and is it really impacting Cardinality Estimates?

There is some guesswork going on in my answer based on the information you've provided. I encourage you to add the actual execution plan and table definitions to your question so that we have all the details involved that might be playing into these implicit conversion issues.

In general, implicit conversion on join conditions can cause serious issues with estimates. It's hard to say if this is happening in your case without seeing the actual execution plan.