最近项目上在做性能测试,收到了很多优化需求,数量之多,一口吃不下,于是给项目组讲了一下嵌套查询,尽量自己先看看是否可以优化。
嵌套顾名思义就是一层层的循环套在一起,类似于多个for循环套在一起.
假设以下例子中有3个表嵌套查询,不考虑优化器自动改写sql的情况下。
select * from table_a a ,table_b b ,table_c c where a.id='aaaaaaa' and a.real_id=b.real_id and c.real_id=b.real_id
伪代码可能是如下
for(select * from table_a where a.id='aaaaaaa'){
for (select * from table_b where b.real_id=a.real_id){
for (select * from table_c where c.real_id=b.real_id){
}
}
}
外层的for叫做外循环,外循环中没查询一条记录,都要到内循环中执行一次查询,示例中table_a是table_b的外循环,table_b是table_c的外循环
演化成sql的执行计划可能如下展示
| ID | OPERATOR | NAME | EST.ROWS | COST |
|---|---|---|---|---|
| 0 | NESTED-LOOP JOIN | |||
| 1 | NESTED-LOOP JOIN | |||
| 2 | TABLE_SCAN | A.INDEX | ||
| 3 | TABLE_SCAN | B.INDEX | ||
| 4 | TABLE_SCAN | C.INDEX |
执行计划中处于相同缩进的算子中(id=2和id=3),上面(id=2)是外循环,下面(id=3)的是内循环,A是B表的外循环,然后A表和B表的结果作为C表的外循环。如果这样的执行计划我们如何优化那?
1、首先我们要保证外循环可以使用索引,既在A表的id列上创建索引。
2、内循环的谓词条件中增加索引,既在B表的real_id列上创建索引。
创建索引也得考虑采样啊、基数啊、直方图等很多因素,这里只是一个简单的实例,讲解了一下什么是嵌套查询。
最后修改时间:2023-06-03 10:19:00
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




