What Rules Determine When SQL Server Use a CTE as an “Optimization Fence”?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
7
down vote

favorite












A while back, Brent Ozar published a post detailing some of the differences between the SQL Server and PostgreSQL:



Two Important Differences Between SQL Server and PostgreSQL



The first point (“CTEs are optimization fences”) caught my eye, because it is obvious that in the example provided, SQL Server combines the CTE and the main query together and optimizes it as a single query (as opposed to the opposite behavior in PostgreSQL).



However, this behavior seems contrary to the examples that I have seen in other blogs and training classes, where SQL Server does treat the CTE as an optimization fence, which allows for better use of indexes, better performance, etc. For example:



A Better Way To Select Star



So, it seems like SQL Server “honors” the CTE as an optimization fence SOMETIMES. Are there any good resources available that document the specific list of known cases where SQL Server will reliably honor the CTE as an optimization fence (or the opposite behavior)?










share|improve this question























  • "list of x" questions are generally off-topic, but I have done my best to answer within the scope of this site.
    – Paul White♦
    1 hour ago
















up vote
7
down vote

favorite












A while back, Brent Ozar published a post detailing some of the differences between the SQL Server and PostgreSQL:



Two Important Differences Between SQL Server and PostgreSQL



The first point (“CTEs are optimization fences”) caught my eye, because it is obvious that in the example provided, SQL Server combines the CTE and the main query together and optimizes it as a single query (as opposed to the opposite behavior in PostgreSQL).



However, this behavior seems contrary to the examples that I have seen in other blogs and training classes, where SQL Server does treat the CTE as an optimization fence, which allows for better use of indexes, better performance, etc. For example:



A Better Way To Select Star



So, it seems like SQL Server “honors” the CTE as an optimization fence SOMETIMES. Are there any good resources available that document the specific list of known cases where SQL Server will reliably honor the CTE as an optimization fence (or the opposite behavior)?










share|improve this question























  • "list of x" questions are generally off-topic, but I have done my best to answer within the scope of this site.
    – Paul White♦
    1 hour ago












up vote
7
down vote

favorite









up vote
7
down vote

favorite











A while back, Brent Ozar published a post detailing some of the differences between the SQL Server and PostgreSQL:



Two Important Differences Between SQL Server and PostgreSQL



The first point (“CTEs are optimization fences”) caught my eye, because it is obvious that in the example provided, SQL Server combines the CTE and the main query together and optimizes it as a single query (as opposed to the opposite behavior in PostgreSQL).



However, this behavior seems contrary to the examples that I have seen in other blogs and training classes, where SQL Server does treat the CTE as an optimization fence, which allows for better use of indexes, better performance, etc. For example:



A Better Way To Select Star



So, it seems like SQL Server “honors” the CTE as an optimization fence SOMETIMES. Are there any good resources available that document the specific list of known cases where SQL Server will reliably honor the CTE as an optimization fence (or the opposite behavior)?










share|improve this question















A while back, Brent Ozar published a post detailing some of the differences between the SQL Server and PostgreSQL:



Two Important Differences Between SQL Server and PostgreSQL



The first point (“CTEs are optimization fences”) caught my eye, because it is obvious that in the example provided, SQL Server combines the CTE and the main query together and optimizes it as a single query (as opposed to the opposite behavior in PostgreSQL).



However, this behavior seems contrary to the examples that I have seen in other blogs and training classes, where SQL Server does treat the CTE as an optimization fence, which allows for better use of indexes, better performance, etc. For example:



A Better Way To Select Star



So, it seems like SQL Server “honors” the CTE as an optimization fence SOMETIMES. Are there any good resources available that document the specific list of known cases where SQL Server will reliably honor the CTE as an optimization fence (or the opposite behavior)?







sql-server query-performance optimization cte






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 1 hour ago









sp_BlitzErik

20.4k1162103




20.4k1162103










asked 1 hour ago









Bryan Rebok

68929




68929











  • "list of x" questions are generally off-topic, but I have done my best to answer within the scope of this site.
    – Paul White♦
    1 hour ago
















  • "list of x" questions are generally off-topic, but I have done my best to answer within the scope of this site.
    – Paul White♦
    1 hour ago















"list of x" questions are generally off-topic, but I have done my best to answer within the scope of this site.
– Paul White♦
1 hour ago




"list of x" questions are generally off-topic, but I have done my best to answer within the scope of this site.
– Paul White♦
1 hour ago










1 Answer
1






active

oldest

votes

















up vote
6
down vote














...list of known cases where SQL Server will reliably honor the CTE as an optimization fence




Any such list would rely on observed behaviour, with no guarantee of reliability.



The SQL Server query optimizer never treats a common table expression as an optimization fence per se, though some constructions are clearly difficult to optimize across. Recursive CTEs are a good example of this.



CTEs are treated very similarly to views/inline functions/subqueries/derived tables and inlined into the query. Any observed 'fence' behaviour depends on the optimizer either not being able to, or deciding not to, optimize across that in-principle permeable border.



Generally speaking, the simpler and more 'relational' the CTE is, the more likely it is that the optimizer will be able to move bits around.



Features that would allow the optimizer to consider, or force it to materialize the 'result' of a CTE have been suggested, but not yet implemented:



  • The optimizer should considering materialising results of CTEs

  • Additional Query Hint: OPTION (MATERIALIZE (cte_name,...,n)

In the meantime, the most common workaround is to explicitly materialize the intermediate result set in a temporary table or table variable. This obviously requires a scenario not limited to a single statement.






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',
    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%2f221555%2fwhat-rules-determine-when-sql-server-use-a-cte-as-an-optimization-fence%23new-answer', 'question_page');

    );

    Post as a guest






























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    6
    down vote














    ...list of known cases where SQL Server will reliably honor the CTE as an optimization fence




    Any such list would rely on observed behaviour, with no guarantee of reliability.



    The SQL Server query optimizer never treats a common table expression as an optimization fence per se, though some constructions are clearly difficult to optimize across. Recursive CTEs are a good example of this.



    CTEs are treated very similarly to views/inline functions/subqueries/derived tables and inlined into the query. Any observed 'fence' behaviour depends on the optimizer either not being able to, or deciding not to, optimize across that in-principle permeable border.



    Generally speaking, the simpler and more 'relational' the CTE is, the more likely it is that the optimizer will be able to move bits around.



    Features that would allow the optimizer to consider, or force it to materialize the 'result' of a CTE have been suggested, but not yet implemented:



    • The optimizer should considering materialising results of CTEs

    • Additional Query Hint: OPTION (MATERIALIZE (cte_name,...,n)

    In the meantime, the most common workaround is to explicitly materialize the intermediate result set in a temporary table or table variable. This obviously requires a scenario not limited to a single statement.






    share|improve this answer


























      up vote
      6
      down vote














      ...list of known cases where SQL Server will reliably honor the CTE as an optimization fence




      Any such list would rely on observed behaviour, with no guarantee of reliability.



      The SQL Server query optimizer never treats a common table expression as an optimization fence per se, though some constructions are clearly difficult to optimize across. Recursive CTEs are a good example of this.



      CTEs are treated very similarly to views/inline functions/subqueries/derived tables and inlined into the query. Any observed 'fence' behaviour depends on the optimizer either not being able to, or deciding not to, optimize across that in-principle permeable border.



      Generally speaking, the simpler and more 'relational' the CTE is, the more likely it is that the optimizer will be able to move bits around.



      Features that would allow the optimizer to consider, or force it to materialize the 'result' of a CTE have been suggested, but not yet implemented:



      • The optimizer should considering materialising results of CTEs

      • Additional Query Hint: OPTION (MATERIALIZE (cte_name,...,n)

      In the meantime, the most common workaround is to explicitly materialize the intermediate result set in a temporary table or table variable. This obviously requires a scenario not limited to a single statement.






      share|improve this answer
























        up vote
        6
        down vote










        up vote
        6
        down vote










        ...list of known cases where SQL Server will reliably honor the CTE as an optimization fence




        Any such list would rely on observed behaviour, with no guarantee of reliability.



        The SQL Server query optimizer never treats a common table expression as an optimization fence per se, though some constructions are clearly difficult to optimize across. Recursive CTEs are a good example of this.



        CTEs are treated very similarly to views/inline functions/subqueries/derived tables and inlined into the query. Any observed 'fence' behaviour depends on the optimizer either not being able to, or deciding not to, optimize across that in-principle permeable border.



        Generally speaking, the simpler and more 'relational' the CTE is, the more likely it is that the optimizer will be able to move bits around.



        Features that would allow the optimizer to consider, or force it to materialize the 'result' of a CTE have been suggested, but not yet implemented:



        • The optimizer should considering materialising results of CTEs

        • Additional Query Hint: OPTION (MATERIALIZE (cte_name,...,n)

        In the meantime, the most common workaround is to explicitly materialize the intermediate result set in a temporary table or table variable. This obviously requires a scenario not limited to a single statement.






        share|improve this answer















        ...list of known cases where SQL Server will reliably honor the CTE as an optimization fence




        Any such list would rely on observed behaviour, with no guarantee of reliability.



        The SQL Server query optimizer never treats a common table expression as an optimization fence per se, though some constructions are clearly difficult to optimize across. Recursive CTEs are a good example of this.



        CTEs are treated very similarly to views/inline functions/subqueries/derived tables and inlined into the query. Any observed 'fence' behaviour depends on the optimizer either not being able to, or deciding not to, optimize across that in-principle permeable border.



        Generally speaking, the simpler and more 'relational' the CTE is, the more likely it is that the optimizer will be able to move bits around.



        Features that would allow the optimizer to consider, or force it to materialize the 'result' of a CTE have been suggested, but not yet implemented:



        • The optimizer should considering materialising results of CTEs

        • Additional Query Hint: OPTION (MATERIALIZE (cte_name,...,n)

        In the meantime, the most common workaround is to explicitly materialize the intermediate result set in a temporary table or table variable. This obviously requires a scenario not limited to a single statement.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 20 mins ago

























        answered 1 hour ago









        Paul White♦

        48k14257407




        48k14257407



























             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f221555%2fwhat-rules-determine-when-sql-server-use-a-cte-as-an-optimization-fence%23new-answer', 'question_page');

            );

            Post as a guest













































































            Comments

            Popular posts from this blog

            Long meetings (6-7 hours a day): Being “babysat” by supervisor

            Is the Concept of Multiple Fantasy Races Scientifically Flawed? [closed]

            Confectionery