Implicit Conversion of VARCHAR Column to NVARCHAR does not cause expected table scanMysql int vs varchar as...

I need to drive a 7/16" nut but am unsure how to use the socket I bought for my screwdriver

Why is stat::st_size 0 for devices but at the same time lseek defines the device size correctly?

Why does Deadpool say "You're welcome, Canada," after shooting Ryan Reynolds in the end credits?

How Did the Space Junk Stay in Orbit in Wall-E?

Ban on all campaign finance?

Why would a flight no longer considered airworthy be redirected like this?

How to get the name of the database a stored procedure is executed in within that stored procedure while it's executing?

2D counterpart of std::array in C++17

How to simplify this time periods definition interface?

Old race car problem/puzzle

My adviser wants to be the first author

Rejected in 4th interview round citing insufficient years of experience

Possible Leak In Concrete

Theorems like the Lovász Local Lemma?

How do anti-virus programs start at Windows boot?

How to generate globally unique ids for different tables of the same database?

Professor being mistaken for a grad student

Have researchers managed to "reverse time"? If so, what does that mean for physics?

Is Mortgage interest accrued after a December payment tax deductible?

At what level can a dragon innately cast its spells?

Check this translation of Amores 1.3.26

Informing my boss about remarks from a nasty colleague

Instead of Universal Basic Income, why not Universal Basic NEEDS?

Is it normal that my co-workers at a fitness company criticize my food choices?



Implicit Conversion of VARCHAR Column to NVARCHAR does not cause expected table scan


Mysql int vs varchar as primary key (InnoDB Storage Engine?SHOWPLAN does not display a warning but “Include Execution Plan” does for the same queryReading a SQL Server Execution planHow to avoid implicit conversion for an Integer columnMySQL not using index on large WHERE IN clauseImplicit conversion does not affect performanceInsert results of spBlitzIndex stored procedure into tablePlan changes to include Eager Spool causes the query to run slowerUNION ALL implicit conversion for VARCHAR(MAX) columnWhy does this SQL Server execution plan contain a snapshot cursor for a select statement?













0















Given the following script, I can see implicit conversion and Data type precendence have a negative impact on a query plan



-- create objects
CREATE DATABASE ConvertTest
GO

USE ConvertTest
GO

CREATE TABLE Person
(
VarcharId NVARCHAR(4),
IntId INT
)

-- insert data
INSERT INTO Person
SELECT TOP 1000
CONVERT(NVARCHAR(4),ROW_NUMBER() OVER (ORDER BY a.object_id)),
ROW_NUMBER() OVER (ORDER BY a.object_id)
FROM sys.objects a
CROSS JOIN sys.objects b

-- create indexes
CREATE INDEX IX_Varchar ON Person
(
VarcharId,
IntId
)

CREATE INDEX IX_Int ON Person
(
IntId,
VarcharId
)

DECLARE @id NVARCHAR(4) = 100
-- statement 1
SELECT * FROM Person WHERE VarcharId = @id
-- index seek

-- statement 2
SELECT * FROM Person WHERE IntId = @id
-- index seek
GO

DECLARE @id INT = 100

-- statement 3
SELECT * FROM Person WHERE VarcharId = @id
-- index scan

-- statement 4
SELECT * FROM Person WHERE IntId = @id
-- index seek


Query 3 implicitly converts the VarcharId column to int (which has higher precendence) and this causes the predicate to be non SARGable and thus causes a table scan.



However, when I run a similar test, I did not get the results I expected:



-- create objects
CREATE DATABASE ConvertTest2
GO

USE ConvertTest2
GO

CREATE TABLE Ids
(
NvarId NVARCHAR(4),
VarId VARCHAR(4)
)


-- insert data
INSERT INTO Ids
SELECT TOP 1000
CONVERT(NVARCHAR(4),ROW_NUMBER() OVER (ORDER BY a.object_id)),
CONVERT(VARCHAR(4),ROW_NUMBER() OVER (ORDER BY a.object_id))
FROM sys.objects a
CROSS JOIN sys.objects b

-- create indexes
CREATE INDEX IX_NvarId ON Ids
(
NvarId,
VarId
)

CREATE INDEX IX_VarId ON Ids
(
VarId,
NvarId
)

DECLARE @id NVARCHAR(4) = 10
SELECT * FROM Ids WHERE NvarId = @id
SELECT * FROM Ids WHERE VarId = @id
GO

DECLARE @id VARCHAR(4) = 10
SELECT * FROM Ids WHERE NvarId = @id
SELECT * FROM Ids WHERE VarId = @id


All four queries show an index seek (although query two runs the seek through a nested loop with a computer scalar)



Given that NVARCHAR has a higher data type precendence than VARCHAR, I expected to see the VarId column implicitly converted to a VARCHAR and therefore causing a table scan.



Why / how does datatype precendence bahave differently when converting between varchar / nvarchar types?









share



























    0















    Given the following script, I can see implicit conversion and Data type precendence have a negative impact on a query plan



    -- create objects
    CREATE DATABASE ConvertTest
    GO

    USE ConvertTest
    GO

    CREATE TABLE Person
    (
    VarcharId NVARCHAR(4),
    IntId INT
    )

    -- insert data
    INSERT INTO Person
    SELECT TOP 1000
    CONVERT(NVARCHAR(4),ROW_NUMBER() OVER (ORDER BY a.object_id)),
    ROW_NUMBER() OVER (ORDER BY a.object_id)
    FROM sys.objects a
    CROSS JOIN sys.objects b

    -- create indexes
    CREATE INDEX IX_Varchar ON Person
    (
    VarcharId,
    IntId
    )

    CREATE INDEX IX_Int ON Person
    (
    IntId,
    VarcharId
    )

    DECLARE @id NVARCHAR(4) = 100
    -- statement 1
    SELECT * FROM Person WHERE VarcharId = @id
    -- index seek

    -- statement 2
    SELECT * FROM Person WHERE IntId = @id
    -- index seek
    GO

    DECLARE @id INT = 100

    -- statement 3
    SELECT * FROM Person WHERE VarcharId = @id
    -- index scan

    -- statement 4
    SELECT * FROM Person WHERE IntId = @id
    -- index seek


    Query 3 implicitly converts the VarcharId column to int (which has higher precendence) and this causes the predicate to be non SARGable and thus causes a table scan.



    However, when I run a similar test, I did not get the results I expected:



    -- create objects
    CREATE DATABASE ConvertTest2
    GO

    USE ConvertTest2
    GO

    CREATE TABLE Ids
    (
    NvarId NVARCHAR(4),
    VarId VARCHAR(4)
    )


    -- insert data
    INSERT INTO Ids
    SELECT TOP 1000
    CONVERT(NVARCHAR(4),ROW_NUMBER() OVER (ORDER BY a.object_id)),
    CONVERT(VARCHAR(4),ROW_NUMBER() OVER (ORDER BY a.object_id))
    FROM sys.objects a
    CROSS JOIN sys.objects b

    -- create indexes
    CREATE INDEX IX_NvarId ON Ids
    (
    NvarId,
    VarId
    )

    CREATE INDEX IX_VarId ON Ids
    (
    VarId,
    NvarId
    )

    DECLARE @id NVARCHAR(4) = 10
    SELECT * FROM Ids WHERE NvarId = @id
    SELECT * FROM Ids WHERE VarId = @id
    GO

    DECLARE @id VARCHAR(4) = 10
    SELECT * FROM Ids WHERE NvarId = @id
    SELECT * FROM Ids WHERE VarId = @id


    All four queries show an index seek (although query two runs the seek through a nested loop with a computer scalar)



    Given that NVARCHAR has a higher data type precendence than VARCHAR, I expected to see the VarId column implicitly converted to a VARCHAR and therefore causing a table scan.



    Why / how does datatype precendence bahave differently when converting between varchar / nvarchar types?









    share

























      0












      0








      0








      Given the following script, I can see implicit conversion and Data type precendence have a negative impact on a query plan



      -- create objects
      CREATE DATABASE ConvertTest
      GO

      USE ConvertTest
      GO

      CREATE TABLE Person
      (
      VarcharId NVARCHAR(4),
      IntId INT
      )

      -- insert data
      INSERT INTO Person
      SELECT TOP 1000
      CONVERT(NVARCHAR(4),ROW_NUMBER() OVER (ORDER BY a.object_id)),
      ROW_NUMBER() OVER (ORDER BY a.object_id)
      FROM sys.objects a
      CROSS JOIN sys.objects b

      -- create indexes
      CREATE INDEX IX_Varchar ON Person
      (
      VarcharId,
      IntId
      )

      CREATE INDEX IX_Int ON Person
      (
      IntId,
      VarcharId
      )

      DECLARE @id NVARCHAR(4) = 100
      -- statement 1
      SELECT * FROM Person WHERE VarcharId = @id
      -- index seek

      -- statement 2
      SELECT * FROM Person WHERE IntId = @id
      -- index seek
      GO

      DECLARE @id INT = 100

      -- statement 3
      SELECT * FROM Person WHERE VarcharId = @id
      -- index scan

      -- statement 4
      SELECT * FROM Person WHERE IntId = @id
      -- index seek


      Query 3 implicitly converts the VarcharId column to int (which has higher precendence) and this causes the predicate to be non SARGable and thus causes a table scan.



      However, when I run a similar test, I did not get the results I expected:



      -- create objects
      CREATE DATABASE ConvertTest2
      GO

      USE ConvertTest2
      GO

      CREATE TABLE Ids
      (
      NvarId NVARCHAR(4),
      VarId VARCHAR(4)
      )


      -- insert data
      INSERT INTO Ids
      SELECT TOP 1000
      CONVERT(NVARCHAR(4),ROW_NUMBER() OVER (ORDER BY a.object_id)),
      CONVERT(VARCHAR(4),ROW_NUMBER() OVER (ORDER BY a.object_id))
      FROM sys.objects a
      CROSS JOIN sys.objects b

      -- create indexes
      CREATE INDEX IX_NvarId ON Ids
      (
      NvarId,
      VarId
      )

      CREATE INDEX IX_VarId ON Ids
      (
      VarId,
      NvarId
      )

      DECLARE @id NVARCHAR(4) = 10
      SELECT * FROM Ids WHERE NvarId = @id
      SELECT * FROM Ids WHERE VarId = @id
      GO

      DECLARE @id VARCHAR(4) = 10
      SELECT * FROM Ids WHERE NvarId = @id
      SELECT * FROM Ids WHERE VarId = @id


      All four queries show an index seek (although query two runs the seek through a nested loop with a computer scalar)



      Given that NVARCHAR has a higher data type precendence than VARCHAR, I expected to see the VarId column implicitly converted to a VARCHAR and therefore causing a table scan.



      Why / how does datatype precendence bahave differently when converting between varchar / nvarchar types?









      share














      Given the following script, I can see implicit conversion and Data type precendence have a negative impact on a query plan



      -- create objects
      CREATE DATABASE ConvertTest
      GO

      USE ConvertTest
      GO

      CREATE TABLE Person
      (
      VarcharId NVARCHAR(4),
      IntId INT
      )

      -- insert data
      INSERT INTO Person
      SELECT TOP 1000
      CONVERT(NVARCHAR(4),ROW_NUMBER() OVER (ORDER BY a.object_id)),
      ROW_NUMBER() OVER (ORDER BY a.object_id)
      FROM sys.objects a
      CROSS JOIN sys.objects b

      -- create indexes
      CREATE INDEX IX_Varchar ON Person
      (
      VarcharId,
      IntId
      )

      CREATE INDEX IX_Int ON Person
      (
      IntId,
      VarcharId
      )

      DECLARE @id NVARCHAR(4) = 100
      -- statement 1
      SELECT * FROM Person WHERE VarcharId = @id
      -- index seek

      -- statement 2
      SELECT * FROM Person WHERE IntId = @id
      -- index seek
      GO

      DECLARE @id INT = 100

      -- statement 3
      SELECT * FROM Person WHERE VarcharId = @id
      -- index scan

      -- statement 4
      SELECT * FROM Person WHERE IntId = @id
      -- index seek


      Query 3 implicitly converts the VarcharId column to int (which has higher precendence) and this causes the predicate to be non SARGable and thus causes a table scan.



      However, when I run a similar test, I did not get the results I expected:



      -- create objects
      CREATE DATABASE ConvertTest2
      GO

      USE ConvertTest2
      GO

      CREATE TABLE Ids
      (
      NvarId NVARCHAR(4),
      VarId VARCHAR(4)
      )


      -- insert data
      INSERT INTO Ids
      SELECT TOP 1000
      CONVERT(NVARCHAR(4),ROW_NUMBER() OVER (ORDER BY a.object_id)),
      CONVERT(VARCHAR(4),ROW_NUMBER() OVER (ORDER BY a.object_id))
      FROM sys.objects a
      CROSS JOIN sys.objects b

      -- create indexes
      CREATE INDEX IX_NvarId ON Ids
      (
      NvarId,
      VarId
      )

      CREATE INDEX IX_VarId ON Ids
      (
      VarId,
      NvarId
      )

      DECLARE @id NVARCHAR(4) = 10
      SELECT * FROM Ids WHERE NvarId = @id
      SELECT * FROM Ids WHERE VarId = @id
      GO

      DECLARE @id VARCHAR(4) = 10
      SELECT * FROM Ids WHERE NvarId = @id
      SELECT * FROM Ids WHERE VarId = @id


      All four queries show an index seek (although query two runs the seek through a nested loop with a computer scalar)



      Given that NVARCHAR has a higher data type precendence than VARCHAR, I expected to see the VarId column implicitly converted to a VARCHAR and therefore causing a table scan.



      Why / how does datatype precendence bahave differently when converting between varchar / nvarchar types?







      performance sql-server-2014 execution-plan datatypes type-conversion





      share












      share










      share



      share










      asked 2 mins ago









      SEarle1986SEarle1986

      477316




      477316






















          0






          active

          oldest

          votes











          Your Answer








          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "182"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f232196%2fimplicit-conversion-of-varchar-column-to-nvarchar-does-not-cause-expected-table%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes
















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Database Administrators Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f232196%2fimplicit-conversion-of-varchar-column-to-nvarchar-does-not-cause-expected-table%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Parapolítica Índice Antecedentes El escándalo Proceso judicial Consecuencias Véase...

          How to remove border from elements in the last row?Targeting flex items on the last rowHow to vertically wrap...

          Tecnologías entrañables Índice Antecedentes Desarrollo Tecnologías Entrañables en la...