Sql-server – Implicit conversion: when does it hurt performance a lot

datatypessql servert-sqltype conversion

I know that when data types are the same it is good and it hurts performance when they are not.

But sometimes it seems to have very little impact and basically a waste of time to fix it. Other times it will have a huge impact and performance gets a lot better.

Of course there are many scenarios, e.g. a insert select where the data type of the select is not the same, but compatible, with the insert column. Or it could be on the join predicates.

Where does implicit conversion hurt the most?

Also it seems that one also gets an implicit conversion when the lengths don't match, e.g. joining varchar(10) with varchar(20). How big a deal is these scenarios when we are only dealing with the length of the columns and not their type?

Basically I would like to know when I should worry about the compute scalar operator in the execution plan. How can I know if removing it will have a significant impact?

Best Answer

There are two main issues which cause implicit (or explicit) conversion to make a big difference to the query plan:

The main point of problems is where a join or filter predicate, or an ordering or grouping, is over a converted column. Note also that this applies equally to any function on a column used in such a context. A column which is just selected has far less impact.

This means firstly, that the compiler cannot use an index lookup to get the data, nor can it rely on the conversion output to be in the correct order for operations such as a Merge join or Stream Aggregate.

This particular point is far more insidious than some realize. With some conversions, for example int to float, the compiler understands these to be order-preserving. But conversions such as varchar to nvarchar have no such semantic.

Therefore often, when joining on say varchar and nvarchar column, it is necessary to decide which table will be the one to be seeked, and therefore often an explicit conversion is better.

The second issue is the more well-known one: no statistics. The compiler has no understanding of what the result of the conversion implies, therefore it cannot use statistics to determine estimated rowcounts and densities. This can often affect the whole plan, and often makes a bigger difference the deeper in the plan it is.


If the conversion or function is only in the select (and is not predicated in outer parts of the query), then there is far less impact, even though the same warning occurs. In this case, normally the conversion will happen just before the row is output from the query, it does not normally affect anytthe query plan.

Two cases where select can make a difference are:

  • Conversions to much larger types, such as the LOB max types. it is beneficial to ensure that the conversion happens as late as possible.
  • Very complex nested string functions, that are passed to each other via CROSS APPLY. Here, the opposite is true: do the calculation earlier, and prevent the compiler trying to nest the whole thing as one big Compute Scalar. OUTER APPLY is your friend, it seems to give an optimization-fence effect.