Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. Database & SysAdmin
  3. Database
  4. SQL Server Query Plan Cache Behavior

SQL Server Query Plan Cache Behavior

Scheduled Pinned Locked Moved Database
databasequestioncsharpsql-serversysadmin
13 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F Foothill

    Not at all. Here's the watered down, abreviated version of the code that generates the INSERT statement. There's a lot more going on but this is the meat of it.

    // The values to insert are contained in the Properties of container class, I'll call it IData for this example
    List columns = new List();
    List variables = new List();
    string sqlStatement = null;

    // Dynamically create and execute a parameterized SqlStatement
    using (SqlCommand command = new SqlCommand() { CommandType = CommandType.Text, Connection = connection })
    {
    // IData is a container class that holds the properties and the name of the table that the object is stored in
    // The IProperty object contains the name of the column, the Sql Data Type to use, and the value to insert
    foreach (IProperty prop in IData.Properties)
    {
    columns.Add(prop.TableColumnName);
    variables.Add("@" + prop.TableColumnName);

    // Create the parameter
    var currentParameter = new Parameter("@" + prop.TableColumnName, prop.SqlType);
    currentParameter.Value = (objProp.Value == null) ? DBNull.Value : objProp.Value;
    command.Parameters.Add(currentParameter);
    }

    sqlStatement = String.Join(" ", new string[]
    {
    "INSERT INTO dbo." + IData.TableName,
    "(" + String.Join(", ", columns.ToArray()) + ")",
    "VALUES (" + String.Join(", ", variables.ToArray()) + ");"
    });

    command.CommandText = sqlStatement;
    command.ExecuteNonQuery();
    }

    if (Object.DividedByZero == true) { Universe.Implode(); }

    J Offline
    J Offline
    Jorgen Andersson
    wrote on last edited by
    #4

    But you're still not defining the size as far as I can see, so it will be inferred from the value of the dbType parameter if it is not explicitly set in the size parameter.[^]

    Wrong is evil and must be defeated. - Jeff Ello

    F 1 Reply Last reply
    0
    • J Jorgen Andersson

      But you're still not defining the size as far as I can see, so it will be inferred from the value of the dbType parameter if it is not explicitly set in the size parameter.[^]

      Wrong is evil and must be defeated. - Jeff Ello

      F Offline
      F Offline
      Foothill
      wrote on last edited by
      #5

      Ah, so the reason for the multitude of cached query plans is that when dealing with variable length text a new plan is created when a parameter's length is different from a previous plan? So basically, if I want the server to not create new plans, I need to define the size of the variable length parameters?

      if (Object.DividedByZero == true) { Universe.Implode(); }

      J 1 Reply Last reply
      0
      • F Foothill

        Ah, so the reason for the multitude of cached query plans is that when dealing with variable length text a new plan is created when a parameter's length is different from a previous plan? So basically, if I want the server to not create new plans, I need to define the size of the variable length parameters?

        if (Object.DividedByZero == true) { Universe.Implode(); }

        J Offline
        J Offline
        Jorgen Andersson
        wrote on last edited by
        #6

        Yes.

        Wrong is evil and must be defeated. - Jeff Ello

        F 1 Reply Last reply
        0
        • J Jorgen Andersson

          Yes.

          Wrong is evil and must be defeated. - Jeff Ello

          F Offline
          F Offline
          Foothill
          wrote on last edited by
          #7

          That makes sense. Does the Size represent the size of the data or the size of the field in the database? I would assume that's in bytes also.

          if (Object.DividedByZero == true) { Universe.Implode(); }

          Richard DeemingR 1 Reply Last reply
          0
          • F Foothill

            That makes sense. Does the Size represent the size of the data or the size of the field in the database? I would assume that's in bytes also.

            if (Object.DividedByZero == true) { Universe.Implode(); }

            Richard DeemingR Online
            Richard DeemingR Online
            Richard Deeming
            wrote on last edited by
            #8

            Bytes for binary types; characters for string types: SqlParameter.Size Property (System.Data.SqlClient)[^]


            "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

            "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

            F 1 Reply Last reply
            0
            • Richard DeemingR Richard Deeming

              Bytes for binary types; characters for string types: SqlParameter.Size Property (System.Data.SqlClient)[^]


              "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

              F Offline
              F Offline
              Foothill
              wrote on last edited by
              #9

              Got it. Now all I have to do is weigh the overhead of calculating sizes (when and where) vs additional query plans in the cache. Thanks for helping to clear this up.

              if (Object.DividedByZero == true) { Universe.Implode(); }

              J 1 Reply Last reply
              0
              • F Foothill

                Got it. Now all I have to do is weigh the overhead of calculating sizes (when and where) vs additional query plans in the cache. Thanks for helping to clear this up.

                if (Object.DividedByZero == true) { Universe.Implode(); }

                J Offline
                J Offline
                Jorgen Andersson
                wrote on last edited by
                #10

                It would be pretty hard to calculate, since the correct size would be what the size of the field in the database table is defined as. So there are two ways to go if you want to keep generating your DML. Either you ask the database what the field sizes are, Or you define them in your classes using an Attribute on your properties. You get the SizeAttribute for a member using ((SizeAttribute)Member.GetCustomAttributes(typeof(SizeAttribute), true)[0]).FieldName;

                Wrong is evil and must be defeated. - Jeff Ello

                F 1 Reply Last reply
                0
                • J Jorgen Andersson

                  It would be pretty hard to calculate, since the correct size would be what the size of the field in the database table is defined as. So there are two ways to go if you want to keep generating your DML. Either you ask the database what the field sizes are, Or you define them in your classes using an Attribute on your properties. You get the SizeAttribute for a member using ((SizeAttribute)Member.GetCustomAttributes(typeof(SizeAttribute), true)[0]).FieldName;

                  Wrong is evil and must be defeated. - Jeff Ello

                  F Offline
                  F Offline
                  Foothill
                  wrote on last edited by
                  #11

                  Not so much in this instance. For the above example, the IProperty object also includes a definition class which already has a MaxLength field, along with other database specific information, which is the size of the database field. I used that size first on text fields but noticed that some fields were getting extra empty characters appended to the end of the text to fill the size of the field, so I stopped using it. If I understand correctly, I should be passing the length of the data to the SqlParameter. The extra overhead I was referring to was casting the IData object to it's appropriate type (boxing and unboxing overhead) then getting the length from string.Length or byte[].Length. Trying to weigh which overhead has greater impact, code conversion or database query plans.

                  if (Object.DividedByZero == true) { Universe.Implode(); }

                  J 1 Reply Last reply
                  0
                  • F Foothill

                    Not so much in this instance. For the above example, the IProperty object also includes a definition class which already has a MaxLength field, along with other database specific information, which is the size of the database field. I used that size first on text fields but noticed that some fields were getting extra empty characters appended to the end of the text to fill the size of the field, so I stopped using it. If I understand correctly, I should be passing the length of the data to the SqlParameter. The extra overhead I was referring to was casting the IData object to it's appropriate type (boxing and unboxing overhead) then getting the length from string.Length or byte[].Length. Trying to weigh which overhead has greater impact, code conversion or database query plans.

                    if (Object.DividedByZero == true) { Universe.Implode(); }

                    J Offline
                    J Offline
                    Jorgen Andersson
                    wrote on last edited by
                    #12

                    Foothill wrote:

                    I should be passing the length of the data to the SqlParameter.

                    Maxlength is what you want to pass[^], that you got empty character appended is something I've never heard of before. You didn't by any chance use Char instead of Varchar? Char gets padded to the size specified.

                    Foothill wrote:

                    Trying to weigh which overhead has greater impact, code conversion or database query plans.

                    Database query plans, without any doubts.

                    Wrong is evil and must be defeated. - Jeff Ello

                    F 1 Reply Last reply
                    0
                    • J Jorgen Andersson

                      Foothill wrote:

                      I should be passing the length of the data to the SqlParameter.

                      Maxlength is what you want to pass[^], that you got empty character appended is something I've never heard of before. You didn't by any chance use Char instead of Varchar? Char gets padded to the size specified.

                      Foothill wrote:

                      Trying to weigh which overhead has greater impact, code conversion or database query plans.

                      Database query plans, without any doubts.

                      Wrong is evil and must be defeated. - Jeff Ello

                      F Offline
                      F Offline
                      Foothill
                      wrote on last edited by
                      #13

                      MaxLength it is and all the text fields are NVarchar(N) by default. Since I should use the MaxLength field, it would be trivial to add a couple of lines in the code that executes the INSERT statement to handle the variable length data. Thanks again.

                      if (Object.DividedByZero == true) { Universe.Implode(); }

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups