-- start
當我們執行一條查詢語句的時候,我們只告訴 oracle 我們想要哪些資料,至於資料在**,怎麼找,那是查詢優化器的事情,優化器需要改寫查詢語句,決定訪問路徑(如:全表掃瞄,快速全索引掃瞄,索引掃瞄),決定表聯接順序等。至於選擇哪種方式,優化器需要根據資料字典做出判斷。
那優化器如何改寫查詢語句呢?
第一種方法叫合併檢視,如果你的查詢語句中引用了檢視,那麼優化器會把檢視合併到查詢中,下面是乙個簡單的例子,需要注意的是優化器也不是神,如果你的檢視包含集合操作符,聚合函式,group by 等,優化器也傻了,不知道如何合併了。
-- 檢視定義
create view employees_50_vw as
select employee_id, last_name, job_id, salary, commission_pct, department_id
from employees
where department_id = 50;
-- 查詢語句
select employee_id
from employees_50_vw
where employee_id > 150;
-- 合併檢視後的查詢語句
select employee_id
from employees
where department_id = 50
and employee_id > 150;
第二種方法叫謂詞推進(predicate pushing),對於那些無法執行合併檢視的查詢語句,oracle 會把查詢語句中的條件挪到檢視中,下面是乙個簡單的例子。
-- 檢視定義
create view all_employees_vw as
(select employee_id, last_name, job_id, commission_pct, department_id from employees)
union
(select employee_id, last_name, job_id, commission_pct, department_id from contract_workers);
-- 查詢語句的查詢語句
select last_name
from all_employees_vw
where department_id = 50;
-- 謂詞推進
select last_name
from (
select employee_id, last_name, job_id, commission_pct, department_id from employees
where department_id=50 -- 注意此處
union
select employee_id, last_name, job_id, commission_pct, department_id from contract_workers
where department_id=50 -- 注意此處
);
第三種方法是將非巢狀子查詢轉化為表連線。下面是乙個簡單的例子。需要注意的是,並不是所有的非巢狀子查詢都能轉化為表連線,對於下面的例子而言,如果 customers.cust_id 不是主鍵,轉化後會產生笛卡爾集。
-- 非巢狀子查詢
select *
from sales
where cust_id in (select cust_id from customers);
-- 表連線
select sales.*
from sales, customers
where sales.cust_id = customers.cust_id;
第四種方法是使用物化檢視改寫查詢,物化檢視是將乙個查詢的結果集儲存在乙個表中,如果你的查詢語句和某個物化檢視相容,那麼 oracle 就可以直接從物化檢視中取得資料。
--更多參見:oracle sql 優化精萃
-- last edited on 2015-07-10
-- created by shangbo on 2015-07-10
-- end
Oracle查詢優化改寫 1
對應的第一章 單錶查詢 1.將空值轉換為實際值 和nvl函式相比,coalesce函式更好用,後者支援多個引數。coalesce 語法 coalesce exp1,exp2,exp3,功能 9i新增,依次查詢各引數,遇到非null則返回,各引數或表示式資料型別必須一致,如果都為null則返回null...
Oracle查詢優化改寫 2
對應的第二章 給查詢結果排序 1.按指定列排序select ename,comm from emp order by comm asc select ename,comm from emp orderby2 asc 按照第二列排序2.translate函式語法 translate string,fr...
Oracle查詢優化改寫 抄書學習02
3.10 聚集和內連線 員工獎金根據type計算,type 1 的為10 type 2 的wei20 以此類推 先把獎金跟員工彙總,在於員工表關聯。select e.deptno sum e.sal as total sal sum e.sal eb2.rate as total bonus fro...