嵌套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