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







New contributor




Ashraf is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

























    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







    New contributor




    Ashraf is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.























      3












      3








      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







      New contributor




      Ashraf is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.












      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







      New contributor




      Ashraf is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      share|improve this question







      New contributor




      Ashraf is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      share|improve this question




      share|improve this question






      New contributor




      Ashraf is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked 6 hours ago









      AshrafAshraf

      162




      162




      New contributor




      Ashraf is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      Ashraf is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      Ashraf is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






















          1 Answer
          1






          active

          oldest

          votes


















          5














          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

























            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
            });


            }
            });






            Ashraf is a new contributor. Be nice, and check out our Code of Conduct.










            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









            5














            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






























              5














              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




























                5












                5








                5







                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 1 hour ago

























                answered 2 hours ago









                Max VernonMax Vernon

                50.1k13111220




                50.1k13111220






















                    Ashraf is a new contributor. Be nice, and check out our Code of Conduct.










                    draft saved

                    draft discarded


















                    Ashraf is a new contributor. Be nice, and check out our Code of Conduct.













                    Ashraf is a new contributor. Be nice, and check out our Code of Conduct.












                    Ashraf is a new contributor. Be nice, and check out our Code of Conduct.
















                    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

                    Statuo de Libereco

                    Tanganjiko

                    Liste der Baudenkmäler in Enneberg