Execution Plan is different when Constant Variable is Null












3















I am working on a scenario in which I am providing a variable a value. When I pass Null value, the Query Engine didn't scan the Join tables. As per Logical Query Processing, first FROM Clause Executes, then ON and JOIN executes. But in this Case the Query Engine direct go to Where Clause. Could anyone please explain the Behavior Query Engine when there is a NULL value of a Variable. I am using SQL Server 2016.



enter image description here



When the Value is changed then



enter image description here










share|improve this question



























    3















    I am working on a scenario in which I am providing a variable a value. When I pass Null value, the Query Engine didn't scan the Join tables. As per Logical Query Processing, first FROM Clause Executes, then ON and JOIN executes. But in this Case the Query Engine direct go to Where Clause. Could anyone please explain the Behavior Query Engine when there is a NULL value of a Variable. I am using SQL Server 2016.



    enter image description here



    When the Value is changed then



    enter image description here










    share|improve this question

























      3












      3








      3


      0






      I am working on a scenario in which I am providing a variable a value. When I pass Null value, the Query Engine didn't scan the Join tables. As per Logical Query Processing, first FROM Clause Executes, then ON and JOIN executes. But in this Case the Query Engine direct go to Where Clause. Could anyone please explain the Behavior Query Engine when there is a NULL value of a Variable. I am using SQL Server 2016.



      enter image description here



      When the Value is changed then



      enter image description here










      share|improve this question














      I am working on a scenario in which I am providing a variable a value. When I pass Null value, the Query Engine didn't scan the Join tables. As per Logical Query Processing, first FROM Clause Executes, then ON and JOIN executes. But in this Case the Query Engine direct go to Where Clause. Could anyone please explain the Behavior Query Engine when there is a NULL value of a Variable. I am using SQL Server 2016.



      enter image description here



      When the Value is changed then



      enter image description here







      sql-server query-performance sql-server-2016 optimization execution-plan






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Jan 15 at 13:35









      AshrafAshraf

      184




      184






















          1 Answer
          1






          active

          oldest

          votes


















          7














          You're seeing an example of contradiction detection. SQL Server's query optimizer is smart enough to perform a few quick checks at the outset of query processing to determine if it can take any shortcuts to return results without doing much (any?!) work. One such short circuit is to check if the where clause contains an "impossible" limit, such as:



          WHERE 1=0


          or



          WHERE NULL = NULL


          SQL Server sees you are comparing something to NULL, which always returns false, and simply returns an empty resultset. If the items in your WHERE clause were separated with OR instead of AND, then further checks would be performed and you might not see the constant-scan plan.



          Comparing any value to NULL using = always returns false. You may want to use WHERE @c IS NULL instead. If you rewrite your query using that syntax, you'll see SQL Server does in fact "run" the query. Consider this:



          IF OBJECT_ID(N'tempdb..#t', N'U') IS NOT NULL DROP TABLE #t;
          CREATE TABLE #t
          (
          i int NOT NULL
          );

          DECLARE @c int = 1;


          The query plan for this query:



          SELECT *
          FROM #t t
          WHERE t.i = 1
          AND @c = NULL;


          enter image description here



          Versus the query plan for this query:



          SELECT *
          FROM #t t
          WHERE t.i = 1
          AND @c IS NULL;


          enter image description here



          The problems around comparing NULL values applies to JOIN conditions as well. Consider this:



          IF OBJECT_ID(N'tempdb..#t', N'U') IS NOT NULL DROP TABLE #t;
          CREATE TABLE #t
          (
          i int NULL
          );

          IF OBJECT_ID(N'tempdb..#s', N'U') IS NOT NULL DROP TABLE #s;
          CREATE TABLE #s
          (
          i int NULL
          );



          I'll insert a row into each table with the value of i set to NULL:



          INSERT INTO #t (i) VALUES (NULL);
          INSERT INTO #s (i) VALUES (NULL);


          Now, if we try to JOIN the two tables in a "simple" query, we get no results returned, since NULL cannot be compared to anything, not even another NULL value!



          SELECT *
          FROM #t t
          INNER JOIN #s s ON t.i = s.i;


          enter image description here



          Both tables are scanned by the query processor, as shown in the query plan:



          enter image description here



          In other words, be careful using NULL values.





          In future, please don't post pictures of code, instead create a minimal, complete, and verifiable example that others can use in their answer.






          share|improve this answer





















          • 1





            Thank You Max. Really appreciate your effort in explaining the above logic. I will be very careful in future about the code in pictures. Thanks Once again.

            – Ashraf
            Jan 17 at 6:01











          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%2f227188%2fexecution-plan-is-different-when-constant-variable-is-null%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          7














          You're seeing an example of contradiction detection. SQL Server's query optimizer is smart enough to perform a few quick checks at the outset of query processing to determine if it can take any shortcuts to return results without doing much (any?!) work. One such short circuit is to check if the where clause contains an "impossible" limit, such as:



          WHERE 1=0


          or



          WHERE NULL = NULL


          SQL Server sees you are comparing something to NULL, which always returns false, and simply returns an empty resultset. If the items in your WHERE clause were separated with OR instead of AND, then further checks would be performed and you might not see the constant-scan plan.



          Comparing any value to NULL using = always returns false. You may want to use WHERE @c IS NULL instead. If you rewrite your query using that syntax, you'll see SQL Server does in fact "run" the query. Consider this:



          IF OBJECT_ID(N'tempdb..#t', N'U') IS NOT NULL DROP TABLE #t;
          CREATE TABLE #t
          (
          i int NOT NULL
          );

          DECLARE @c int = 1;


          The query plan for this query:



          SELECT *
          FROM #t t
          WHERE t.i = 1
          AND @c = NULL;


          enter image description here



          Versus the query plan for this query:



          SELECT *
          FROM #t t
          WHERE t.i = 1
          AND @c IS NULL;


          enter image description here



          The problems around comparing NULL values applies to JOIN conditions as well. Consider this:



          IF OBJECT_ID(N'tempdb..#t', N'U') IS NOT NULL DROP TABLE #t;
          CREATE TABLE #t
          (
          i int NULL
          );

          IF OBJECT_ID(N'tempdb..#s', N'U') IS NOT NULL DROP TABLE #s;
          CREATE TABLE #s
          (
          i int NULL
          );



          I'll insert a row into each table with the value of i set to NULL:



          INSERT INTO #t (i) VALUES (NULL);
          INSERT INTO #s (i) VALUES (NULL);


          Now, if we try to JOIN the two tables in a "simple" query, we get no results returned, since NULL cannot be compared to anything, not even another NULL value!



          SELECT *
          FROM #t t
          INNER JOIN #s s ON t.i = s.i;


          enter image description here



          Both tables are scanned by the query processor, as shown in the query plan:



          enter image description here



          In other words, be careful using NULL values.





          In future, please don't post pictures of code, instead create a minimal, complete, and verifiable example that others can use in their answer.






          share|improve this answer





















          • 1





            Thank You Max. Really appreciate your effort in explaining the above logic. I will be very careful in future about the code in pictures. Thanks Once again.

            – Ashraf
            Jan 17 at 6:01
















          7














          You're seeing an example of contradiction detection. SQL Server's query optimizer is smart enough to perform a few quick checks at the outset of query processing to determine if it can take any shortcuts to return results without doing much (any?!) work. One such short circuit is to check if the where clause contains an "impossible" limit, such as:



          WHERE 1=0


          or



          WHERE NULL = NULL


          SQL Server sees you are comparing something to NULL, which always returns false, and simply returns an empty resultset. If the items in your WHERE clause were separated with OR instead of AND, then further checks would be performed and you might not see the constant-scan plan.



          Comparing any value to NULL using = always returns false. You may want to use WHERE @c IS NULL instead. If you rewrite your query using that syntax, you'll see SQL Server does in fact "run" the query. Consider this:



          IF OBJECT_ID(N'tempdb..#t', N'U') IS NOT NULL DROP TABLE #t;
          CREATE TABLE #t
          (
          i int NOT NULL
          );

          DECLARE @c int = 1;


          The query plan for this query:



          SELECT *
          FROM #t t
          WHERE t.i = 1
          AND @c = NULL;


          enter image description here



          Versus the query plan for this query:



          SELECT *
          FROM #t t
          WHERE t.i = 1
          AND @c IS NULL;


          enter image description here



          The problems around comparing NULL values applies to JOIN conditions as well. Consider this:



          IF OBJECT_ID(N'tempdb..#t', N'U') IS NOT NULL DROP TABLE #t;
          CREATE TABLE #t
          (
          i int NULL
          );

          IF OBJECT_ID(N'tempdb..#s', N'U') IS NOT NULL DROP TABLE #s;
          CREATE TABLE #s
          (
          i int NULL
          );



          I'll insert a row into each table with the value of i set to NULL:



          INSERT INTO #t (i) VALUES (NULL);
          INSERT INTO #s (i) VALUES (NULL);


          Now, if we try to JOIN the two tables in a "simple" query, we get no results returned, since NULL cannot be compared to anything, not even another NULL value!



          SELECT *
          FROM #t t
          INNER JOIN #s s ON t.i = s.i;


          enter image description here



          Both tables are scanned by the query processor, as shown in the query plan:



          enter image description here



          In other words, be careful using NULL values.





          In future, please don't post pictures of code, instead create a minimal, complete, and verifiable example that others can use in their answer.






          share|improve this answer





















          • 1





            Thank You Max. Really appreciate your effort in explaining the above logic. I will be very careful in future about the code in pictures. Thanks Once again.

            – Ashraf
            Jan 17 at 6:01














          7












          7








          7







          You're seeing an example of contradiction detection. SQL Server's query optimizer is smart enough to perform a few quick checks at the outset of query processing to determine if it can take any shortcuts to return results without doing much (any?!) work. One such short circuit is to check if the where clause contains an "impossible" limit, such as:



          WHERE 1=0


          or



          WHERE NULL = NULL


          SQL Server sees you are comparing something to NULL, which always returns false, and simply returns an empty resultset. If the items in your WHERE clause were separated with OR instead of AND, then further checks would be performed and you might not see the constant-scan plan.



          Comparing any value to NULL using = always returns false. You may want to use WHERE @c IS NULL instead. If you rewrite your query using that syntax, you'll see SQL Server does in fact "run" the query. Consider this:



          IF OBJECT_ID(N'tempdb..#t', N'U') IS NOT NULL DROP TABLE #t;
          CREATE TABLE #t
          (
          i int NOT NULL
          );

          DECLARE @c int = 1;


          The query plan for this query:



          SELECT *
          FROM #t t
          WHERE t.i = 1
          AND @c = NULL;


          enter image description here



          Versus the query plan for this query:



          SELECT *
          FROM #t t
          WHERE t.i = 1
          AND @c IS NULL;


          enter image description here



          The problems around comparing NULL values applies to JOIN conditions as well. Consider this:



          IF OBJECT_ID(N'tempdb..#t', N'U') IS NOT NULL DROP TABLE #t;
          CREATE TABLE #t
          (
          i int NULL
          );

          IF OBJECT_ID(N'tempdb..#s', N'U') IS NOT NULL DROP TABLE #s;
          CREATE TABLE #s
          (
          i int NULL
          );



          I'll insert a row into each table with the value of i set to NULL:



          INSERT INTO #t (i) VALUES (NULL);
          INSERT INTO #s (i) VALUES (NULL);


          Now, if we try to JOIN the two tables in a "simple" query, we get no results returned, since NULL cannot be compared to anything, not even another NULL value!



          SELECT *
          FROM #t t
          INNER JOIN #s s ON t.i = s.i;


          enter image description here



          Both tables are scanned by the query processor, as shown in the query plan:



          enter image description here



          In other words, be careful using NULL values.





          In future, please don't post pictures of code, instead create a minimal, complete, and verifiable example that others can use in their answer.






          share|improve this answer















          You're seeing an example of contradiction detection. SQL Server's query optimizer is smart enough to perform a few quick checks at the outset of query processing to determine if it can take any shortcuts to return results without doing much (any?!) work. One such short circuit is to check if the where clause contains an "impossible" limit, such as:



          WHERE 1=0


          or



          WHERE NULL = NULL


          SQL Server sees you are comparing something to NULL, which always returns false, and simply returns an empty resultset. If the items in your WHERE clause were separated with OR instead of AND, then further checks would be performed and you might not see the constant-scan plan.



          Comparing any value to NULL using = always returns false. You may want to use WHERE @c IS NULL instead. If you rewrite your query using that syntax, you'll see SQL Server does in fact "run" the query. Consider this:



          IF OBJECT_ID(N'tempdb..#t', N'U') IS NOT NULL DROP TABLE #t;
          CREATE TABLE #t
          (
          i int NOT NULL
          );

          DECLARE @c int = 1;


          The query plan for this query:



          SELECT *
          FROM #t t
          WHERE t.i = 1
          AND @c = NULL;


          enter image description here



          Versus the query plan for this query:



          SELECT *
          FROM #t t
          WHERE t.i = 1
          AND @c IS NULL;


          enter image description here



          The problems around comparing NULL values applies to JOIN conditions as well. Consider this:



          IF OBJECT_ID(N'tempdb..#t', N'U') IS NOT NULL DROP TABLE #t;
          CREATE TABLE #t
          (
          i int NULL
          );

          IF OBJECT_ID(N'tempdb..#s', N'U') IS NOT NULL DROP TABLE #s;
          CREATE TABLE #s
          (
          i int NULL
          );



          I'll insert a row into each table with the value of i set to NULL:



          INSERT INTO #t (i) VALUES (NULL);
          INSERT INTO #s (i) VALUES (NULL);


          Now, if we try to JOIN the two tables in a "simple" query, we get no results returned, since NULL cannot be compared to anything, not even another NULL value!



          SELECT *
          FROM #t t
          INNER JOIN #s s ON t.i = s.i;


          enter image description here



          Both tables are scanned by the query processor, as shown in the query plan:



          enter image description here



          In other words, be careful using NULL values.





          In future, please don't post pictures of code, instead create a minimal, complete, and verifiable example that others can use in their answer.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Jan 15 at 18:29

























          answered Jan 15 at 17:07









          Max VernonMax Vernon

          50.2k13112222




          50.2k13112222








          • 1





            Thank You Max. Really appreciate your effort in explaining the above logic. I will be very careful in future about the code in pictures. Thanks Once again.

            – Ashraf
            Jan 17 at 6:01














          • 1





            Thank You Max. Really appreciate your effort in explaining the above logic. I will be very careful in future about the code in pictures. Thanks Once again.

            – Ashraf
            Jan 17 at 6:01








          1




          1





          Thank You Max. Really appreciate your effort in explaining the above logic. I will be very careful in future about the code in pictures. Thanks Once again.

          – Ashraf
          Jan 17 at 6:01





          Thank You Max. Really appreciate your effort in explaining the above logic. I will be very careful in future about the code in pictures. Thanks Once again.

          – Ashraf
          Jan 17 at 6:01


















          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%2f227188%2fexecution-plan-is-different-when-constant-variable-is-null%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

          How to send String Array data to Server using php in android

          Title Spacing in Bjornstrup Chapter, Removing Chapter Number From Contents

          Is anime1.com a legal site for watching anime?