为什么CTE比连接更快

时间:2014-01-29 06:29:22

标签: sql join common-table-expression with-statement

我已经读过With语句的性能在某些情况下比连接要好得多。但是,在加入varchars时(我通常会避免这种情况),当我用With

替换连接时,我看到速度有了很大提高

例如,我有三个我想加入的表:Customer, CustomerNickname, Address(不是一个真实的例子,但会针对这个问题)

我通常会使用以下查询来检索数据:

select * from customer c
inner join address a on c.addressid = a.id
left join CustomerNickname cn on cn.originalname = c.name --name and original name are varchars

如果这些表有大量数据,由于varchar连接,性能将非常糟糕。但是,如果我用以下内容替换查​​询:

  with Nicknames as (
         select * from CustomerNickname
   )
    select * from customer c
    inner join address a on c.addressid = a.id
    left join Nicknames cn on cn.originalname = c.name
性能会大大提高。在我的例子中(我没有在这里添加它,因为它是太多的表),查询从一分钟到一秒钟。此外,我在原始查询的执行计划中注意到,SORT运算符的成本为95%。这是从哪里来的。

所以,有两个问题:

  • 为什么这么快?

  • SORT运算符来自执行计划中的哪个位置。

1 个答案:

答案 0 :(得分:0)

查询将varchar连接到varchar,因此将执行扫描操作。即使使用索引,这也非常昂贵。 Why does Mysql use a full table scan for table A when joining another table B? 我怀疑CTE在服务器的RAM中保持动态状态,因此速度要快得多。 (将CTE的整个结果集从磁盘加载到未排序的RAM中。)