Why CTE (Common Table Expressions) in some cases slow down queries comparing to temporary tables in SQL Server

后端 未结 3 960
予麋鹿
予麋鹿 2021-02-07 09:56

I have several cases where my complex CTE (Common Table Expressions) are ten times slower than the same queries using the temporary tables in SQL

3条回答
  •  挽巷
    挽巷 (楼主)
    2021-02-07 10:48

    The answer is simple.

    SQL Server doesn't materialise CTEs. It inlines them, as you can see from the execution plans.

    Other DBMS may implement it differently, a well-known example is Postgres, which does materialise CTEs (it essentially creates temporary tables for CTEs behind the hood).

    Whether explicit materialisation of intermediary results in explicit temporary tables is faster, depends on the query.

    In complex queries the overhead of writing and reading intermediary data into temporary tables can be offset by more efficient simpler execution plans that optimiser is able to generate.

    On the other hand, in Postgres CTE is an "optimisation fence" and engine can't push predicates across CTE boundary.

    Sometimes one way is better, sometimes another. Once the query complexity grows beyond certain threshold an optimiser can't analyse all possible ways to process the data and it has to settle on something. For example, the order in which to join the tables. The number of permutations grows exponentially with the number of tables to choose from. Optimiser has limited time to generate a plan, so it may make a poor choice when all CTEs are inlined. When you manually break complex query into smaller simpler ones you need to understand what you are doing, but optimiser has a better chance to generate a good plan for each simple query.

提交回复
热议问题