我已经读过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
运算符来自执行计划中的哪个位置。
答案 0 :(得分:0)
查询将varchar连接到varchar,因此将执行扫描操作。即使使用索引,这也非常昂贵。 Why does Mysql use a full table scan for table A when joining another table B? 我怀疑CTE在服务器的RAM中保持动态状态,因此速度要快得多。 (将CTE的整个结果集从磁盘加载到未排序的RAM中。)