国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > Oracle > 正文

ORACLE SQL性能優化系列 (二)

2024-08-29 13:31:25
字體:
來源:轉載
供稿:網友

4. 選擇最有效率的表名順序(只在基于規則的優化器中有效)

oracle的解析器按照從右到左的順序處理from子句中的表名,因此from子句中寫在最后的表(基礎表 driving table)將被最先處理. 在from子句中包含多個表的情況下,你必須選擇記錄條數最少的表作為基礎表.當oracle處理多個表時, 會運用排序及合并的方式連接它們.首先,掃描第一個表(from子句中最后的那個表)并對記錄進行派序,然后掃描第二個表(from子句中最后第二個表),最后將所有從第二個表中檢索出的記錄與第一個表中合適記錄進行合并.

 

例如:

     表 tab1 16,384 條記錄

     表 tab2 1      條記錄

 

     選擇tab2作為基礎表 (最好的方法)

     select count(*) from tab1,tab2   執行時間0.96秒

    

    選擇tab2作為基礎表 (不佳的方法)

     select count(*) from tab2,tab1   執行時間26.09秒

 

如果有3個以上的表連接查詢, 那就需要選擇交叉表(intersection table)作為基礎表, 交叉表是指那個被其他表所引用的表.

 

例如:

 

   emp表描述了location表和category表的交集.

 

 select *

from location l ,

      category c,

      emp e

where e.emp_no between 1000 and 2000

and e.cat_no = c.cat_no

and e.locn = l.locn

 

將比下列sql更有效率

 

select *

from emp e ,

location l ,

      category c

where  e.cat_no = c.cat_no

and e.locn = l.locn

and e.emp_no between 1000 and 2000

 

 

5.       where子句中的連接順序.

 

oracle采用自下而上的順序解析where子句,根據這個原理,表之間的連接必須寫在其他where條件之前, 那些可以過濾掉最大數量記錄的條件必須寫在where子句的末尾.

 

例如:

 

(低效,執行時間156.3秒)

select …

from emp e

where  sal > 50000

and    job = ‘manager’

and    25 < (select count(*) from emp

             where mgr=e.empno);

 

(高效,執行時間10.6秒)

select …

from emp e

where 25 < (select count(*) from emp

             where mgr=e.empno)

and    sal > 50000

and    job = ‘manager’;

 

 

6.     select子句中避免使用 ‘ * ‘

當你想在select子句中列出所有的column時,使用動態sql列引用 ‘*’ 是一個方便的方法.不幸的是,這是一個非常低效的方法. 實際上,oracle在解析的過程中, 會將’*’ 依次轉換成所有的列名, 這個工作是通過查詢數據字典完成的, 這意味著將耗費更多的時間.

   

 

7.     減少訪問數據庫的次數

當執行每條sql語句時, oracle在內部執行了許多工作: 解析sql語句, 估算索引的利用率, 綁定變量 , 讀數據塊等等. 由此可見, 減少訪問數據庫的次數 , 就能實際上減少oracle的工作量.

 

例如,

    以下有三種方法可以檢索出雇員號等于0342或0291的職員.

 

方法1 (最低效)

    select emp_name , salary , grade

    from emp

    where emp_no = 342;

    

    select emp_name , salary , grade

    from emp

    where emp_no = 291;

 

方法2 (次低效)

   

    declare

        cursor c1 (e_no number) is

        select emp_name,salary,grade

        from emp

        where emp_no = e_no;

    begin

        open c1(342);

        fetch c1 into …,..,.. ;

        …..

        open c1(291);

       fetch c1 into …,..,.. ;

         close c1;

      end;

 

 

 

 

 

方法3 (高效)

 

    select a.emp_name , a.salary , a.grade,

            b.emp_name , b.salary , b.grade

    from emp a,emp b

    where a.emp_no = 342

    and   b.emp_no = 291;

 

 

注意:

    在sql*plus , sql*forms和pro*c中重新設置arraysize參數, 可以增加每次數據庫訪問的檢索數據量 ,建議值為200

 

(待續)


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 云阳县| 南川市| 咸宁市| 翁源县| 南城县| 集贤县| 隆尧县| 濉溪县| 巴青县| 阳高县| 永修县| 阳谷县| 曲沃县| 枞阳县| 南宫市| 西安市| 绥德县| 仲巴县| 黔西县| 建始县| 故城县| 思南县| 焉耆| 仙桃市| 定州市| 濉溪县| 洪湖市| 永昌县| 贵南县| 兴化市| 汝阳县| 上饶县| 农安县| 克东县| 朝阳县| 马边| 嘉善县| 黑水县| 五原县| 临沧市| 蓝田县|