<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    索引使用的注意點

    1)????? 合理使用索引

    索引是數(shù)據(jù)庫中重要的數(shù)據(jù)結(jié)構(gòu),它的根本目的就是為了提高查詢效率。現(xiàn)在大多數(shù)的數(shù)據(jù)庫產(chǎn)品都采用 IBM 最先提出的 ISAM 索引結(jié)構(gòu)。索引的使用要恰到好處,其使用原則如下:

    ●在經(jīng)常進行連接,但是沒有指定為外鍵的列上建立索引,而不經(jīng)常連接的字段則由優(yōu)化器自動生成索引。

    ●在頻繁進行排序或分組(即進行 group by order by 操作)的列上建立索引。

    ●在條件表達式中經(jīng)常用到的不同值較多的列上建立檢索,在不同值少的列上不要建立索引。比如在雇員表的“性別”列上只有“男”與“女”兩個不同值,因此就無必要建立索引。如果建立索引不但不會提高查詢效率,反而會嚴重降低更新速度。

    ●如果待排序的列有多個,可以在這些列上建立復合索引( compound index )。

    ●使用系統(tǒng)工具。如 Informix 數(shù)據(jù)庫有一個 tbcheck 工具,可以在可疑的索引上進行檢查。在一些數(shù)據(jù)庫服務器上,索引可能失效或者因為頻繁操作而使得讀取效率降低,如果一個使用索引的查詢不明不白地慢下來,可以試著用 tbcheck 工具檢查索引的完整性,必要時進行修復。另外,當數(shù)據(jù)庫表更新大量數(shù)據(jù)后,刪除并重建索引可以提高查詢速度。

    2)????? 避免或簡化排序

    應當簡化或避免對大型表進行重復的排序。當能夠利用索引自動以適當?shù)拇涡虍a(chǎn)生輸出時,優(yōu)化器就避免了排序的步驟。以下是一些影響因素:

    ●索引中不包括一個或幾個待排序的列;

    group by order by 子句中列的次序與索引的次序不一樣;

    ●排序的列來自不同的表。

    為了避免不必要的排序,就要正確地增建索引,合理地合并數(shù)據(jù)庫表(盡管有時可能影響表的規(guī)范化,但相對于效率的提高是值得的)。如果排序不可避免,那么應當試圖簡化它,如縮小排序的列的范圍等。

    3)????? 消除對大型表行數(shù)據(jù)的順序存取

    在嵌套查詢中,對表的順序存取對查詢效率可能產(chǎn)生致命的影響。比如采用順序存取策略,一個嵌套 3 層的查詢,如果每層都查詢 1000 行,那么這個查詢就要查詢 10 億行數(shù)據(jù)。避免這種情況的主要方法就是對連接的列進行索引。例如,兩個表:學生表(學號、姓名、年齡……)和選課表(學號、課程號、成績)。如果兩個表要做連接,就要在“學號”這個連接字段上建立索引。

    還可以使用并集來避免順序存取。盡管在所有的檢查列上都有索引,但某些形式的 where 子句強迫優(yōu)化器使用順序存取。下面的查詢將強迫對 orders 表執(zhí)行順序操作:

    SELECT FROM orders WHERE (customer_num=104 AND order_num>1001) OR order_num=1008

    雖然在 customer_num order_num 上建有索引,但是在上面的語句中優(yōu)化器還是使用順序存取路徑掃描整個表。因為這個語句要檢索的是分離的行的集合,所以應該改為如下語句:

    SELECT FROM orders WHERE customer_num=104 AND order_num>1001

    UNION

    SELECT FROM orders WHERE order_num=1008

    這樣就能利用索引路徑處理查詢。

    4)????? 避免相關(guān)子查詢

    一個列的標簽同時在主查詢和 where 子句中的查詢中出現(xiàn),那么很可能當主查詢中的列值改變之后,子查詢必須重新查詢一次。查詢嵌套層次越多,效率越低,因此應當盡量避免子查詢。如果子查詢不可避免,那么要在子查詢中過濾掉盡可能多的行。

    5)????? 避免困難的正規(guī)表達式

    MATCHES LIKE 關(guān)鍵字支持通配符匹配,技術(shù)上叫正規(guī)表達式。但這種匹配特別耗費時間。例如: SELECT FROM customer WHERE zipcode LIKE 98_ _ _

    即使在 zipcode 字段上建立了索引,在這種情況下也還是采用順序掃描的方式。如果把語句改為 SELECT FROM customer WHERE zipcode > 98000 ”,在執(zhí)行查詢時就會利用索引來查詢,顯然會大大提高速度。

    另外,還要避免非開始的子串。例如語句: SELECT FROM customer WHERE zipcode[2 3] > 80 ”,在 where 子句中采用了非開始子串,因而這個語句也不會使用索引。

    6)????? 使用臨時表加速查詢

    把表的一個子集進行排序并創(chuàng)建臨時表,有時能加速查詢。它有助于避免多重排序操作,而且在其他方面還能簡化優(yōu)化器的工作。例如:

    SELECT cust.name , rcvbles.balance ,…… other columns

    FROM cust , rcvbles

    WHERE cust.customer_id = rcvlbes.customer_id

    AND rcvblls.balance>0

    AND cust.postcode>“98000”

    ORDER BY cust.name

    如果這個查詢要被執(zhí)行多次而不止一次,可以把所有未付款的客戶找出來放在一個臨時文件中,并按客戶的名字進行排序:

    SELECT cust.name rcvbles.balance ,…… other columns

    FROM cust , rcvbles

    WHERE cust.customer_id = rcvlbes.customer_id

    AND rcvblls.balance>0

    ORDER BY cust.name

    INTO TEMP cust_with_balance

    然后以下面的方式在臨時表中查詢:

    SELECT FROM cust_with_balance

    WHERE postcode>“98000”

    臨時表中的行要比主表中的行少,而且物理順序就是所要求的順序,減少了磁盤 I/O ,所以查詢工作量可以得到大幅減少。

    注意:臨時表創(chuàng)建后不會反映主表的修改。在主表中數(shù)據(jù)頻繁修改的情況下,注意不要丟失數(shù)據(jù)。

    7)????? 用排序來取代非順序存取

    非順序磁盤存取是最慢的操作,表現(xiàn)在磁盤存取臂的來回移動。 SQL 語句隱藏了這一情況,使得我們在寫應用程序時很容易寫出要求存取大量非順序頁的查詢。

    有些時候,用數(shù)據(jù)庫的排序能力來替代非順序的存取能改進查詢。

    ?

    優(yōu)化SQL語句

    ?

    優(yōu)化就是選擇最有效的方法來執(zhí)行 SQL 語句。 Oracle 優(yōu)化器選擇它認為最有效的方法來執(zhí)行 SQL 語句。  

    1)????? IS NULL IS NOT NULL

    如果某列存在 NULL 值,即使對該列建立索引也不會提高性能。

    2)????? 為不同的工作編寫不同的SQL語句塊。

    為完成不同的工作編寫一大塊 SQL 程序不是好方法。它往往導致每個任務的結(jié)果不優(yōu)

    化。若要 SQL 完成不同的工作,一般應編寫不同的語句塊比編寫一個要好。

    3)????? IN 和EXISTS

    Select name from employee where name not in (select name from student);

    Select name from employee where not exists (select name from student);

    第一句 SQL 語句的執(zhí)行效率不如第二句。

    通過使用 EXISTS , Oracle 會首先檢查主查詢,然后運行子查詢直到它找到第一個匹配

    項,這就節(jié)省了時間。 Oracle 在執(zhí)行 IN 子查詢時,首先執(zhí)行子查詢,并將獲得的結(jié)果

    列表存放在一個加了索引的臨時表中。在執(zhí)行子查詢之前,系統(tǒng)先將主查詢掛起,待

    子查詢執(zhí)行完畢,存放在臨時表中以后再執(zhí)行主查詢。這也就是使用 EXISTS 比使用 IN

    通常查詢速度快的原因。

    4)????? NOT 運算符

    Select * from employee where salary<>1000;

    Select * from employee where salary<1000 or salary>1000;

    第一句 SQL 語句的執(zhí)行效率不如第二句,因為第二句 SQL 語句可以使用索引。

    5)????? Order By 語句

    Order By 語句的執(zhí)行效率很低,因為它要排序。應避免在 Order By 字句中使用表達式。

    6)????? 列的連接

    select * from employee where name||department=’ZYZBIOINFO’;

    select * from employee where name=’ZYZ’ and department=’BIOINFO’;

    這兩個查詢,第二句比第一句會快,因為對于有連接運算符’ || ’的查詢 ,Oracle 優(yōu)化器是不

    會使用索引的。

    7)????? 通配符‘%’當通配符出現(xiàn)在搜索詞首時,Oracle優(yōu)化器不使用索引。

    Select * from employee where name like ‘%Z%’;

    Select * from employee where name like ‘Z%’;

    第二句的執(zhí)行效率會比第一句快,但查詢結(jié)果集可能會不同。

    8)????? 應盡量避免混合類型的表達式。

    假設字段 studentno VARCHAR2 類型

    有語句 select * from student where studentno>123;

    Oracle 會有一個隱含的類型轉(zhuǎn)換。隱含的類型轉(zhuǎn)換可能會使 Oracle 優(yōu)化器忽略索引。

    這時應使用顯式的類型轉(zhuǎn)換 select * from student where studentno=to_char(123) 。

    9)????? DISTINCT

       DISTINCT 總是建立一個排序,所以查詢速度也慢。

    posted on 2006-05-09 17:38 野草 閱讀(638) 評論(0)  編輯  收藏 所屬分類: oracle
    主站蜘蛛池模板: 四虎成人精品在永久免费| mm1313亚洲国产精品美女| 亚洲日韩乱码中文字幕| 免费在线观看a级毛片| 在线涩涩免费观看国产精品| 亚洲精品国产情侣av在线| 免费观看的毛片手机视频| 一本大道一卡二大卡三卡免费| 亚洲国产高清在线| 亚洲日韩精品国产一区二区三区 | 91精品免费久久久久久久久| 伊人久久亚洲综合影院首页| 亚洲熟妇无码乱子AV电影| 成年免费大片黄在线观看岛国| 亚洲第一永久在线观看| 免费在线观看日韩| 91免费在线播放| 国产成人精品免费大全| 国产婷婷综合丁香亚洲欧洲| 情人伊人久久综合亚洲| 成人黄网站片免费视频| 亚洲精品动漫免费二区| 国产成人综合久久精品免费 | 免费中文字幕一级毛片| 亚洲精品免费视频| 色爽黄1000部免费软件下载| 亚洲性线免费观看视频成熟| 国产精品亚洲аv无码播放| 四虎免费久久影院| 国色精品卡一卡2卡3卡4卡免费| 亚洲伊人色一综合网| 成人看的午夜免费毛片| 久久久久免费精品国产小说| 免费无码婬片aaa直播表情| 亚洲精品成人无限看| 免费观看四虎精品国产永久 | 久久精品国产亚洲香蕉| 亚洲男人的天堂一区二区| 亚洲免费无码在线| 国产亚洲视频在线| 亚洲丁香婷婷综合久久|