嵌套SQL的查询速度比较分析

文章中使用Oracle自带的HR数据库,故代码可以直接进行测试。
代码一:

select t.employee_id, t.first_name, t.phone_number  from HR.Employees t where t.first_name like 'A%'
or t.first_name like 'B%'
or  t.first_name like 'H%'
or  t.first_name like 'K%'
or  t.first_name like 'M%'
or  t.first_name like 'J%'
or  t.first_name like 'N%'
执行计划:


代码二:
select * 
from (
select t.employee_id, t.first_name, t.phone_number  from HR.Employees t where t.first_name like 'A%'
or t.first_name like 'B%'
or  t.first_name like 'H%'
or  t.first_name like 'K%'
or  t.first_name like 'M%'
or  t.first_name like 'J%'
or  t.first_name like 'N%'
)
执行计划:


对比:代码1与代码2的执行计划相同

代码三:
select t.employee_id, t.first_name, t.phone_number  from HR.Employees t where t.first_name like 'A%'
union
select t.employee_id, t.first_name, t.phone_number  from HR.Employees t where t.first_name like 'B%'
union
select t.employee_id, t.first_name, t.phone_number  from HR.Employees t where t.first_name like 'H%'
union
select t.employee_id, t.first_name, t.phone_number  from HR.Employees t where t.first_name like 'K%'
union
select t.employee_id, t.first_name, t.phone_number  from HR.Employees t where t.first_name like 'M%'
union
select t.employee_id, t.first_name, t.phone_number  from HR.Employees t where t.first_name like 'J%'
union
select t.employee_id, t.first_name, t.phone_number  from HR.Employees t where t.first_name like 'N%'
执行计划:


代码四:

select * from 
(
select t.employee_id, t.first_name, t.phone_number  from HR.Employees t where t.first_name like 'A%'
union
select t.employee_id, t.first_name, t.phone_number  from HR.Employees t where t.first_name like 'B%'
union
select t.employee_id, t.first_name, t.phone_number  from HR.Employees t where t.first_name like 'H%'
union
select t.employee_id, t.first_name, t.phone_number  from HR.Employees t where t.first_name like 'K%'
union
select t.employee_id, t.first_name, t.phone_number  from HR.Employees t where t.first_name like 'M%'
union
select t.employee_id, t.first_name, t.phone_number  from HR.Employees t where t.first_name like 'J%'
union
select t.employee_id, t.first_name, t.phone_number  from HR.Employees t where t.first_name like 'N%'
)
执行计划:

对比:代码4中Sort Unique与代码3的执行计划相同。但Oracle在处理代码4的查询语句时,构建了一个内部视图来整理查询结果,其中需要21次IO操作,故需要更长的时间。

其他:在一个SQL中,使用“OR”语句比使用多个Union会花费更短的时间。

代码五:
代码5-1:
select *
from
(
select *  from HR.Employees tx where tx.department_id = 50) T1, 
(
select * from HR.Departments ty where ty.department_id < 150) T2
where t1.department_id = t2.department_id
代码5-2:
select *
from
HR.Employees t1, 
HR.Departments T2
where t1.department_id = t2.department_id and t1.department_id = 50 and t2.department_id < 150
代码5-3:
select *
from
HR.Employees T1, 
HR.Departments T2
where t1.department_id = t2.department_id(+and t1.department_id = 50 and t2.department_id <150
代码5-4:
select *
from
HR.Employees T1, 
HR.Departments T2
where t1.department_id(+= t2.department_id and t1.department_id = 50 and t2.department_id <150
代码5-1到代码5-4的Oracle执行计划分析结果相同:

对比:代码5-1到代码5-4的执行计划相同。Oracle是先对T1和T2中数据进行过滤后,再对结果集进行关联查询。且Oracle对表过滤内容进行了优化,对表Departments的查询优化为 TY.Department_ID=50 而不是 TY.Department_ID<150
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述

随笔 - 31, 文章 - 0, 评论 - 78, 阅读 - 43248

Copyright © 2025 joyyuan97
Powered by .NET 9.0 on Kubernetes

点击右上角即可分享
微信分享提示